m.e*_*son 12 c# floating-point types decimal primitive-types
如果我将单个 s转换为十进制 d,我注意到它的位表示与直接创建的小数表示不同.
例如:
Single s = 0.01f;
Decimal d = 0.01m;
int[] bitsSingle = Decimal.GetBits((decimal)s)
int[] bitsDecimal = Decimal.GetBits(d)
Run Code Online (Sandbox Code Playgroud)
返回(为简洁起见,删除了中间元素):
Run Code Online (Sandbox Code Playgroud)bitsSingle: [0] = 10 [3] = 196608 bitsDecimal: [0] = 1 [3] = 131072
这两个都是十进制数,两者(看起来)都准确地表示0.01:

看看这个规范除了可能之外没有任何亮点:
§4.1.7与float和double数据类型相反,0.1等小数小数可以用十进制表示精确表示.
这表明该以某种方式受到单不能够在转换前准确地表示0.01,因此:
两位小数都精确地代表0.1.只是decimal格式,允许多个按位不同的值表示完全相同的数字.
这并不是说single不能精确地代表0.1.根据以下文件GetBits:
数字的二进制表示
Decimal由1位符号,96位整数和用于除以整数的比例因子组成,并指定它的哪个部分是小数.缩放因子隐含地为数字10,增加到范围从0到28的指数.返回值是32位有符号整数的四元素数组.
返回数组的第一,第二和第三个元素包含96位整数的低,中和高32位.
返回数组的第四个元素包含比例因子和符号.它由以下部分组成:
低位字0到15位未使用,必须为零.
位16到23必须包含0到28之间的指数,表示除以整数的10的幂.
第24至30位未使用,必须为零.
位31包含符号:0表示正数,1表示负数.
注意,位表示区分负零和正零.在所有操作中,这些值被视为相等.
decimal示例中每个的第四个整数是0x00030000for bitsSingle和0x00020000for bitsDecimal.在二进制中,这映射到:
bitsSingle 00000000 00000011 00000000 00000000
|\-----/ \------/ \---------------/
| | | |
sign <-+ unused exponent unused
| | | |
|/-----\ /------\ /---------------\
bitsDecimal 00000000 00000010 00000000 00000000
NOTE: exponent represents multiplication by negative power of 10
Run Code Online (Sandbox Code Playgroud)
因此,在第一种情况下,96位整数除以10的附加因子,而第二位16到23给出值3而不是2.但是它被96位整数本身抵消,在第一种情况下也比第二种情况大10倍(显而易见的是第一种元素的值).
因此,观察值的差异可以简单地归因于这样的事实:single与"直"构造函数相比,转换使用微妙不同的逻辑来导出内部表示.
| 归档时间: |
|
| 查看次数: |
266 次 |
| 最近记录: |