简体   繁体   English

获取不舍入的最后 2 个小数位

[英]Get Last 2 Decimal Places with No Rounding

In C#, I'm trying to get the last two decimal places of a double with NO rounding.在 C# 中,我试图在没有四舍五入的情况下获得双精度的最后两位小数。 I've tried everything from Math.Floor to Math.Truncate and nothing is working.我已经尝试了从Math.FloorMath.Truncate所有Math.FloorMath.Truncate没有任何效果。

Samples of the results I'd like:我想要的结果样本:

1,424.2488298 -> 1,424.24
53.5821 -> 53.58
10,209.2991 -> 10,209.29

Any ideas?有任何想法吗?

Well, mathematically it's simple: 好吧,数学上很简单:

var f = 1.1234;
f = Math.Truncate(f * 100) / 100;  // f == 1.12

Move the decimal two places to the right, cast to an int to truncate, shift it back to the left two places. 将小数点后两位移到右侧,转换为int以截断,将其移回左侧两个位置。 There may be ways in the framework to do it too, but I can't look right now. 框架中可能还有一些方法可以做到这一点,但我现在看不出来。 You could generalize it: 你可以概括一下:

double Truncate(double value, int places)
{
    // not sure if you care to handle negative numbers...       
    var f = Math.Pow( 10, places );
    return Math.Truncate( value * f ) / f;
}

My advice: stop using double in the first place . 我的建议:首先停止使用double If you need decimal rounding then odds are good you should be using decimal . 如果你需要十进制舍入,那么赔率是好的,你应该使用decimal What is your application? 你的申请是什么?

If you do have a double, you can do it like this: 如果你有双,你可以这样做:

double r = whatever;
decimal d = (decimal)r;
decimal truncated = decimal.Truncate(d * 100m) / 100m;

Note that this technique will fail if the absolute value of the double is larger than 792281625142643375935439504, because the multiplication by 100 will fail. 请注意,如果double的绝对值大于792281625142643375935439504,则此技术将失败,因为乘以100将失败。 If you need to handle values that large then you'll need to use special techniques. 如果您需要处理大的值,那么您将需要使用特殊技术。 (Of course, by the time a double is that large, you are well beyond its ability to represent values with two digits after the decimal place anyway.) (当然,到双倍大的时候,你的能力远远超出它在小数位后用两位数表示值的能力。)

 double d = Math.Truncate(d * 100) / 100;
Math.Round(NumberToRound - (double)0.005,2)

ie

Math.Round(53.5821 - (double)0.005,2) // 53.58
Math.Round(53.5899 - (double)0.005,2) // 53.58
Math.Round(53.5800 - (double)0.005,2) // 53.58

A general solution: 一般解决方案:

    public static double SignificantTruncate(double num, int significantDigits)
    {
        double y = Math.Pow(10, significantDigits);
        return Math.Truncate(num * y) / y;
    }

Then 然后

    double x = 5.3456;
    x = SignificantTruncate(x,2);

Will produce the desired result x=5.34 . 将产生所需的结果x=5.34

Octane i generalized your answer, it does not suffer from exceeding max values.. works like a charm :) Octane 我概括了你的答案,它不会受到超过最大值的影响..就像一个魅力:)

int dec = 4; 
return Math.Round(val - (decimal)(5 / Math.Pow(10,dec+1)), dec)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM