## Introduction

This is a rewrite of an old post I wrote back in 2019, where I had this odd requirement to truncate a decimal without rounding it. After re-reading the original article, I realized the proposed solutions were flawed in several ways. So here is my second attempt 🤓

## Problem statement

How can arbitrary decimal places be cut from a `decimal` without rounding it? For example, cutting three decimal places from `1.23456` should result in `1.234` and not `1.234`. Let's run through the solutions.

## Math.Truncate solution

The following solution works by shifting places to the left by a multiplier.

``````[Fact]
public void Should_cut_decimal_places_v1()
{
const int value = 1.23456M;
const int places = 3;

var multiplier = (decimal)Math.Pow(10, places);
var actual = Math.Truncate(value * multiplier) / multiplier;

Assert.Equal(1.234M, actual);
}``````

In the example from above, the multiplier will be `1000`. `Math.Truncate(value * multiplier)` will cut the fractional part and result in `1234`. Divided again by the multiplier results in `1.234`. Mission accomplished!

However, there is an issue with the solution from above. In case `value * multiplier` becomes bigger then `Decimal.MaxValue` we will face an overflow. So it's safer to handle the integral and fractional parts separately.

``````[Fact]
public void Should_cut_decimal_places_v2()
{
// Arrange
const decimal value = 1.23456M;
const int places = 3;

// Act
var integral = Math.Truncate(value);
var fraction = value - integral;

var multiplier = (decimal)Math.Pow(10, places);
var truncatedFraction = Math.Truncate(fraction * multiplier) / multiplier;
var actual = integral + truncatedFraction;

// Assert
Assert.Equal(1.234M, actual);
}``````

## Modulo solution

The same goal can be reached by leveraging modulo. In the example below, `value % divisor` becomes `0.00056`, which then subtracted from the original value leads to the desired outcome.

``````[Fact]
public void Should_cut_decimal_places_v3()
{
const decimal value = 1.23456M;
const int places = 3;

var divisor = (decimal)Math.Pow(10, -1 * places); // 0.001
var actual = (value - (value % divisor)); // 1.23400

Assert.Equal(1.234M, actual);
}``````

## Conclusion

Both, the modulo and the shifting approach have led to a solution. Depending on your requirements you might prefer the modulo approach since it's less complex and therefore faster.