Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 双精度vs字符串中的舍入错误。请设置相同的数字格式_C#_Optimization_C# 4.0 - Fatal编程技术网

C# 双精度vs字符串中的舍入错误。请设置相同的数字格式

C# 双精度vs字符串中的舍入错误。请设置相同的数字格式,c#,optimization,c#-4.0,C#,Optimization,C# 4.0,我有一个具有实际值的double(从调试器中可以看到)val=1.5530000000002 然而,如果我像string.Format(“{0}”,val)那样打印它,我会得到“1.553”,这是我正在寻找的实际值 1.5530000000002来自一些套接字API,我无法更改它。但是我需要1.553 我该怎么办 请注意,我每秒收到数千个这样的消息。我负担不起修改数学课程或来回转换它们。有什么安慰吗?基本上,您需要使用十进制数据类型,而不是双精度数据类型。十进制可以存储精确的值,在其精度范围内;

我有一个具有实际值的double(从调试器中可以看到)
val=1.5530000000002

然而,如果我像
string.Format(“{0}”,val)
那样打印它,我会得到“1.553”,这是我正在寻找的实际值

1.5530000000002
来自一些套接字API,我无法更改它。但是我需要1.553

我该怎么办


请注意,我每秒收到数千个这样的消息。我负担不起修改
数学
课程或来回转换它们。有什么安慰吗?

基本上,您需要使用十进制数据类型,而不是双精度数据类型。十进制可以存储精确的值,在其精度范围内;double不能,因此观察到的行为。

这个
数学
类每秒可以完成数千次。因此,您需要做的就是
Math.Floor(val,3)
Math.Round(val,3)
问题是
double
是一个浮点值,它可能不可能精确地容纳
1.553000000000
decimal
类型更适合保存这样的精确值

如果无法在socket API中将
double
更改为
decimal
,则您别无选择,只能使用数学解决此问题。在这种情况下,您需要将
双精度
转换为
十进制
,然后执行数学运算以调整所需的精度

以下是您可以轻松做到这一点的方法:

double value = 1.5530000000000002;
decimal rounded = decimal.Round((decimal)value, 3);

你一定要用双人床吗?如果不是的话,你可以使用Decimal.Round(val,3),例如。

我决定将它们放大到整数。我可以这样做,因为我知道数字中有多少个有效数字

int real = (int)(dbl * multiplier);
我确信小数会变慢,因为我没有x128 CPU和内存总线。使用数学是永远无法解决的问题

很抱歉,模糊的铸造浮动较早

编辑确定。所以我明白了,所以现在不再免费了。每个问题现在都需要注意,这在时间上是昂贵的。。。下面的代码回答了我为什么不使用小数和数学

class Program
{
    static void Main(string[] args)
    {
        Start();
        Console.ReadLine();                
    }

    static int TESTS = 10;
    static int LOOPS = 50000;

    static double d1 = 1.5530000000000002;
    static double d2 = 1.5531;

    static double dResult;
    static int iResult;
    static decimal cResult;

    static void Start()
    {
        // actual test
        for (int x = 0; x < TESTS; x++)
        {
            Stopwatch sw = new Stopwatch();

            long tick1, tick2, tick3;
            sw.Start();
            for (int j = 0; j < LOOPS; j++)
            {
                dResult = Math.Round(d1 / 2.0, 4);
                dResult = Math.Round(d2 / 2.0, 4);
            }
            sw.Stop();

            tick1 = sw.ElapsedTicks;

            sw.Restart();
            for (int j = 0; j < LOOPS; j++)
            {
                iResult = (int)(d1 / 2.0 * 10000.0);
                iResult = (int)(d2 / 2.0 * 10000.0);
            }
            sw.Stop();

            tick2 = sw.ElapsedTicks;

            sw.Restart();
            for (int j = 0; j < LOOPS; j++)
            {
                cResult = decimal.Round((decimal)d1, 4);
                cResult = decimal.Round((decimal)d2, 4);
            }
            sw.Stop();

            tick3 = sw.ElapsedTicks;

            Console.WriteLine("Math {0} Int {1} Decimal {2}", tick1, tick2, tick3);
        }
    }
}
类程序
{
静态void Main(字符串[]参数)
{
Start();
Console.ReadLine();
}
静态int测试=10;
静态int循环=50000;
静态双d1=1.5530000000002;
静态双d2=1.5531;
静态双结果;
静态输入结果;
静态小数结果;
静态void Start()
{
//实际测试
对于(int x=0;x
第一部分是数学,第二部分是我打算使用的(转换为int),第三部分是小数


我的i7上的结果如下-分别为12K、700和35K个刻度。

您如何接收这些?它们是字符串、8字节浮点值还是其他什么?出于好奇,为什么需要精确到1.553?通常,不精确性可以忽略不计,只要您没有进行大量重复计算,误差可能会累积。仅供参考,在双精度中,1.553==1.55299999999999360515378159。下一个可用的数字(我相信)是1.5530000000000009928058375408。所以,公平地说,你收到的数字实际上不是1.553(甚至在双精度范围内),但它非常接近。@all。。号码是1.553,因为我知道是的。我需要它,因为我有一本带钥匙的字典。实际的问题是-为什么格式正确?@gabe如果我从套接字中得到字符串,我就不会问了。这是正确的答案。如果你使用double,你就不能指望它的精确性。如果你想精确的使用十进制。我需要一个大的养老金账户和360天的古巴假期。。。但是是的。需要处理讨厌的替身。@Bobb:试着用插座测量。你接收信息的速度不可能超过你对某件事的四舍五入。当然,你接收信息的速度可以更快。数据不停地流动。套接字中的延迟无关紧要——尽管数据是在200毫秒前发送的,但它仍然在大量流动。另外,这里并不是只有一个插座。。。所以请不要争论。问题是——如何不使用数学。thanks@Bobb:好的,如果你想要我的基准,给你。10000次迭代<代码>数学。圆形
需要1毫秒,
CSng
需要1毫秒,而什么都不做需要0.8毫秒,至少在我的电脑上是这样。你什么也没做,好吧。我不知道从这个网站聊天有多热-让我知道我会给你代码。我测试了50K的数学。四舍五入与乘法和整数转换。。。。数学平均需要12千个记号,整数需要700个记号,比整数快1700%。想打赌吗?请看我答案中的代码。请随意运行它,让我知道它在你的电脑上是如何运行的。你知道你也不能将1.553表示为浮点数,对吗?它实际上类似于1.5529997。@Gabe他的观点是使用
int
scaled最快