## 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.