.net十进制值1m和1.0000m之间是否存在实际差异?
内部存储是不同的:
1m : 0x00000001 0x00000000 0x00000000 0x00000000
1.0000m : 0x000186a0 0x00000000 0x00000000 0x00050000
Run Code Online (Sandbox Code Playgroud)
但是,BCL中的方法是否会使用"有效数字"的知识呢?
我问,因为我正在努力压缩磁盘存储或网络传输的十进制值所需的空间,并且在我存储它之前想要"规范化"该值以提高它的可压缩性.但是,我想知道它是否可能导致问题.我猜它应该没问题,但只是因为我没有看到任何暴露值的精度的方法或属性.有没有人知道呢?
Chr*_*lor 11
编码差异的原因是因为Decimal数据类型将数字存储为整数(96位整数),其中一个标度用于形成除数以获得小数.价值基本上是
integer / 10^scale
Run Code Online (Sandbox Code Playgroud)
在内部,Decimal类型表示为4 Int32,有关更多详细信息,请参阅Decimal.GetBits的文档.总之,GetBits返回一个包含4个Int32的数组,其中每个元素代表Decimal编码的后续部分
Element 0,1,2 - Represent the low, middle and high 32 bits on the 96 bit integer
Element 3 - Bits 0-15 Unused
Bits 16-23 exponent which is the power of 10 to divide the integer by
Bits 24-30 Unused
Bit 31 the sign where 0 is positive and 1 is negative
Run Code Online (Sandbox Code Playgroud)
因此,在您的示例中,非常简单地将1.0000m编码为十进制时实际表示为1,10000 / 10^4而1m表示为1 / 10^0数学上相同的值,只是编码不同.
如果您使用本机.NET运算符作为十进制类型并且不自己操作/比较位/字节,那么您应该是安全的.
您还会注意到,字符串转换也将考虑此二进制表示并生成不同的字符串,因此如果您依赖字符串表示,则需要小心.
该decimal型轨道扩展,因为它在算术重要.如果您手动对两个数字进行长乘法(例如,3.14*5.00),则结果具有6位精度和4 的标度.
要进行乘法运算,请忽略小数点(暂时)并将这两个数字视为整数.
3.14
* 5.00
------
0000 -- 0 * 314 (0 in the one's place)
00000 -- 0 * 314 (0 in the 10's place)
157000 -- 5 * 314 (5 in the 100's place)
------
157000
Run Code Online (Sandbox Code Playgroud)
这为您提供了未缩放的结果.现在,计算表达式中小数点右边的总位数(即4),并在左侧插入小数点4位:
15.7000
Run Code Online (Sandbox Code Playgroud)
该结果虽然相当于15.7的值,但比值15.7更精确.值15.7000具有6位精度,刻度为4; 15.7精度为3位,标度为1.
如果一个人正在尝试进行精确算术,那么跟踪值和结果的精度和比例非常重要,因为它会告诉你关于结果精度的一些信息(请注意,精度与精度不同:用尺子测量某些东西以十分之一英寸的分数毕业,你可以说最好的测量结果,不管你在小数点右边放了多少尾随零,它最多是精确到的十分之一另一种说法是说你的测量结果准确,最好是在规定值的+/- 5/100之内.
我能想到的唯一原因是调用 `ToString 返回源代码中的确切文本表示形式。
Console.WriteLine(1m); // 1
Console.WriteLine(1.000m); // 1.000
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1337 次 |
| 最近记录: |