您能解释一下C#中的双重转换行为吗?

发布于 2025-02-01 10:29:00 字数 977 浏览 4 评论 0 原文

我试图弄清楚为什么会发生这种情况以及C#在这里做什么。

假设我们有一个双重: 277.3599853515625 (这段时间后是13位数字)

,然后 277.3599853515625.ToString() - > “ 277.359985351563”

我们失去了一个数字,看来这个数字被四舍五入。

但是 Math.Round(277.3599853515625,12) - > 277.359985351562 (看起来像正常的数学圆形结果,在舍入的结果中),

我想也许如果我给toString()我想要的格式()我想要的它会做正确的事情(给我整个数字):

2777.3599855515625.tostring( “ 0。#############”) - > “ 277.359985351563” (那是13#标志,仍然失去了数字并舍入),

如果我将最后一个数字从5减少到4,则它会落下:

27777.3598551562 <277.3598551562 4 .tostring(” 0。#############”) - &gt; “ 277.35998535156 2

因此,它显然是在进行舍入,但是舍入规则与正常数学圆形不同。我的第一个想法是,当正常的圆形回合5下降时,它只是在治疗5个不同的地方,to乱会围起来,但请看一下:

2777.359985351562 4999 .tostring(“ 0。########) ######“) - &gt; “ 277.35998535156 3 ”(什么?!!?!?!?!?)

您是否知道这里发生了什么?

我要问的原因是我需要了解如何用另一种语言复制相同的行为。

谢谢。

I'm trying to figure out why this happens and what is C# doing here.

Let's say we have a double: 277.3599853515625 (that's 13 digits after the period)

Then 277.3599853515625.ToString() -> "277.359985351563"

We lost a digit and it looks like the number got rounded UP.

But Math.Round(277.3599853515625,12) -> 277.359985351562 (looks like normal math rounding results in rounding DOWN)

I thought maybe if I give ToString() the formatting I want it would do the correct thing (give me the entire number):

277.3599853515625.ToString("0.#############") -> "277.359985351563" (that's 13 # signs, and still lost a digit and rounded UP)

If I reduce the last digit from 5 to 4, it rounds DOWN:

277.3599853515624.ToString("0.#############") -> "277.359985351562"

So it is clearly doing the rounding, but the rounding rules are different from normal math rounding. My first thought was that it's just treating 5 different, when normal rounding rounds 5 down, the ToString rounds it up, but look at this:

277.3599853515624999.ToString("0.#############") -> "277.359985351563" (WHAT?!?!?!?)

Do you have any idea what is happening here and what exactly C#'s logic in ToString() does?

The reason I'm asking is that I need to understand how to replicate the same behavior in a different language.

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

日暮斜阳 2025-02-08 10:29:00
  1.   277.3599853515625.tostring() - &gt; “ 277.359985351563”
     

      277.3599853515624.ToString(“ 0。#############”) - &gt; “ 277.359985351562”
     

    在这种情况下, toString 方法正在使用 midpointrounding.awayfromzero ,因此这就是为什么当上一个数字为5时它会转换2至3的原因。
    要参考,请使用此链接: https://learn.microsoft.com/en-us/dotnet/api/system.midpointrounding?view=net-6.0#system-midpointrounding-awaytrounding-awayfromzero

  2.   MATH.ROUND(277.3599853515625,12) - &GT; 277.359985351562 **
     

    在这种情况下, MATH.ROUND 使用 MIDPOINTROUNDING.TOEVEN 默认情况下,将中点值转为最接近的偶数数字。需要明确定义特定的 MidPointrounding 如果 toeve 不需要。
    供参考,使用此链接:


  3.   277.35998535156249999.ToString(“ 0。##############”) - &gt; “ 277.359985351563”
     

    (什么?!?!?!?)

    在这里,有两个概念。一个是 toString 认为这
    277.3599853515624999作为 double 类型,因此是16位数字;这就是为什么您获得16位数字。

      console.Writeline(277.359985351562499999.getType()); // system.double;
     

    double-15-16数字(64位)

     十进制-28-29大数字(128位)
     

    因此,如果更改此(277.3599853515624999)为(277.3599853515624999 m .tostring()),
    然后,您将获得277.3599853515624999

    第二个是由
    MIDPOINTROUNDING.AWAYFROMZERO

您可以使用以下代码播放:

    Decimal h1=  277.3599853515624999m;
    string hh= "277.3599853515624999";
    string h = 277.3599853515624999m.ToString();
    Console.WriteLine(277.3599853515624999.GetType()); // System.Double;
    Console.WriteLine(h);
    string hhh = Math.Round(277.345,2,MidpointRounding.AwayFromZero).ToString();
    Console.WriteLine(hhh);

我希望现在有清晰的图片。

  1. 277.3599853515625.ToString() -> "277.359985351563"
    

    or

    277.3599853515624.ToString("0.#############") -> "277.359985351562"
    

    In this case, the ToString method is using MidpointRounding.AwayFromZero so that is why it converts 2 to 3 when the last digit is 5.
    For Reference, use this link: https://learn.microsoft.com/en-us/dotnet/api/system.midpointrounding?view=net-6.0#system-midpointrounding-awayfromzero

  2. Math.Round(277.3599853515625,12) -> 277.359985351562**
    

    In this case, Math.Round uses MidpointRounding.ToEven by default and rounds midpoint values to the nearest even number. Need to explicitly define specific MidpointRounding if ToEven is not required.
    For Reference, use this link: https://learn.microsoft.com/en-us/dotnet/api/system.math.round?view=net-6.0

  3. 277.3599853515624999.ToString("0.#############") -> "277.359985351563"
    

    (WHAT?!?!?!?)

    Here, there are two concepts. One is that ToString considers this
    277.3599853515624999 as Double type, so it is a 16 digit number; that is why you are getting 16 digits.

    Console.WriteLine(277.3599853515624999.GetType()); // System.Double;
    

    Double-15-16 digits (64 bit)

    Decimal -28-29 significant digits (128 bit)
    

    Thus, if change this (277.3599853515624999) to (277.3599853515624999m.ToString()),
    then you get 277.3599853515624999

    And the second one is that there is also rounding done by
    MidpointRounding.AwayFromZero.

You can play with the below code:

    Decimal h1=  277.3599853515624999m;
    string hh= "277.3599853515624999";
    string h = 277.3599853515624999m.ToString();
    Console.WriteLine(277.3599853515624999.GetType()); // System.Double;
    Console.WriteLine(h);
    string hhh = Math.Round(277.345,2,MidpointRounding.AwayFromZero).ToString();
    Console.WriteLine(hhh);

I hope now there is a clear picture.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文