当前位置: 首页 > news >正文

为什么要选择做花卉网站网上做网站怎么防止被骗

为什么要选择做花卉网站,网上做网站怎么防止被骗,用dw做的个人网站,如何建立自己的直播平台文章目录 前言整数表示的缺陷定点小数定点小数加法乘法运算 浮点数IEEE754浮点数标准移码阶码的移码表示 IEEE754中的特殊点两个0非规格化数字正常浮点数无穷大NaN 浮点数简单举例浮点数一些其余特性浮点数计算不符合结合律浮点数舍入规则浮点数与整数之间的相互转换 总结 前言… 文章目录 前言整数表示的缺陷定点小数定点小数加法乘法运算 浮点数IEEE754浮点数标准移码阶码的移码表示 IEEE754中的特殊点两个0非规格化数字正常浮点数无穷大NaN 浮点数简单举例浮点数一些其余特性浮点数计算不符合结合律浮点数舍入规则浮点数与整数之间的相互转换 总结 前言 本文会详细解释浮点数在计算机中的表示读者需要有简单二进制无符号数补码表示的基本知识即可。耐心看完就能掌握计算机中的浮点数的表示及其特点。文中我已经尽量多用图、表帮助大家理解。 整数表示的缺陷 对于 N b i t Nbit Nbit 表示的无符号数其可以表示从 0 − ( 2 N − 1 ) 0 - (2^{N}-1) 0−(2N−1)范围内的所有整数。当 N 32 N32 N32 时其表示的最大值为 ( 2 32 − 1 ) 4 , 294 , 967 , 295 (2^{32}-1)4,294,967,295 (232−1)4,294,967,295 对于用补码表示的 N b i t Nbit Nbit 表示的有符号数其可以表示从 ( − 2 N − 1 ) − ( 2 N − 1 − 1 ) (-2^{N-1})-(2^{N-1}-1) (−2N−1)−(2N−1−1) 范围内的所有整数。当 N 32 N32 N32 时其表示的最大值为 ( 2 31 − 1 ) 2 , 147 , 483 , 647 (2^{31}-1)2,147,483,647 (231−1)2,147,483,647 缺点在于我们无法表示特别大的小数以及特别小的小数以及小数。 例如 3.155692611 × 2 10 3.155692611×2^{10} 3.155692611×210 或 3.155692611 × 2 − 11 3.155692611×2^{-11} 3.155692611×2−11 或一个简单的 1.5 1.5 1.5 定点小数 定点小数即小数点位置固定的小数表示方法。在十进制中以小数 11.1101 11.1101 11.1101 为例其每一位的位权如下图所示 和十进制表示类似大家可以猜到在二进制表示中以 6 b i t 6bit 6bit 形式定点小数 x x . y y y y xx.yyyy xx.yyyy 为例其每一位的位权则如下图所示 此时 11.110 1 2 11.1101_2 11.11012​ 表示的小数十进制下其值为 2 1 0.5 0.25 0.0625 3.8125 210.50.250.06253.8125 210.50.250.06253.8125 按照上方定点小数表示方法可表示的数字范围最小值 x y x\ y x y 全 0 0 0 则为 0 0 0最大值 x y x\ y x y 全 1 1 1 则为 2 1 0.5 0.25 0.125 0.0625 3.9375 210.50.250.1250.06253.9375 210.50.250.1250.06253.9375。表示整数部分的长度为 m m m表示小数部分的长度为 n n n最大值可表示为 ( 2 m − 2 − n ) (2^m-2^{-n}) (2m−2−n)。简单理解全 1 1 1 表示的二进制小数 11.111 1 2 11.1111_2 11.11112​ 加 00.000 1 2 2 − n 00.0001_22^{-n} 00.00012​2−n 即为 100.000 0 2 2 m 100.0000_22^m 100.00002​2m。 定点小数加法乘法运算 为了过程简单 1.5 1.5 1.5 用上方二进制定点小数但小数部分少一位来表示为 01.10 0 2 01.100_2 01.1002​0.5表示为 00.10 0 2 00.100_2 00.1002​。加法则按顺序排列位权相同对应位置相加乘法和十进制数字加法一样分别如下图左右所示。 使用上述定点小数表示法仍旧有效无法表示特别大和特别小的小数。例如 3.155692611234 × 2 10 3.155692611234×2^{10} 3.155692611234×210 或 3.155692611 × 2 − 11 3.155692611×2^{-11} 3.155692611×2−11 浮点数 我们先以十进制科学计数法数字 6.02 × 1 0 23 6.02×10^{23} 6.02×1023 为例 6.02 6.02 6.02 是尾数 ( s i g n i f i c a n d ) (significand) (significand) 23 23 23 是阶码 ( e x p o n e n t ) (exponent) (exponent) 10 10 10 是基数 ( b a s e / r a d i x ) (base/radix) (base/radix)。其中规格化的要求中尾数的最高有效位不为 0 0 0 且小数点左侧只能有一位。 规格化 1.0 × 1 0 − 9 1.0×10^{-9} 1.0×10−9不能是 0.1 × 1 0 − 8 0.1×10^{-8} 0.1×10−8也不能是 10.0 × 1 0 − 10 10.0×10^{-10} 10.0×10−10。 同理扩展到二进制之中则以 1.0 1 2 × 2 − 1 1.01_2×2^{-1} 1.012​×2−1 为例 1.01 1.01 1.01 为尾数 − 1 -1 −1 为阶码 2 2 2 为基数。其中由于二进制中只有 0 0 0 和 1 1 1 除了 0 0 0 之外的每一个规格化之后的二进制小数小数点左侧都为 1 1 1。这就是浮点数。用科学计数法形式更准确表示规格化之后的数字为如下形式 1. x x x . . . x ∗ 2 y y y . . . y 1.xxx...x * 2^{yyy...y} 1.xxx...x∗2yyy...y 。 IEEE754浮点数标准 二进制中除了 0 0 0 之外的所有小数规格化之后小数点左侧都为 1 1 1标准在表示尾数时把它省略尾数部分只表示 x x x . . . x xxx...x xxx...x 部分阶码用于表示 y y y . . . y yyy...y yyy...y 部分首位数符表示数据的正负。 32 b i t 32bit 32bit 单精度浮点数的各个字段及其长度如下图所示 上述 I E E E 754 IEEE754 IEEE754 标准中由一组 32 b i t 32bit 32bit 二进制数计算其表示的小数的公式为 ( − 1 ) S ∗ ( 1.0 s i g n i f i c a n d ) ∗ 2 E x p o n e n t − 127 \color{red}(-1)^S*(1.0significand)*2^{Exponent-127} (−1)S∗(1.0significand)∗2Exponent−127。其阶码要减掉 127 127 127 的原因在于标准采用了移码来表示。具体随后详细解释。 此时一位表示数符 8 8 8 位用于表示阶码阶码位数越多则表示的范围越大。 23 23 23 位表示尾数尾数位数越多则表示的精度越高。 最低有效位 L e a s t S i g n i f i c a n t B i t Least \ Significant \ Bit Least Significant Bit 的位权为 2 − 23 2^{-23} 2−23 具体可类比上方定点小数表示中小数位数及其位权的关系。 移码 移码本身非常容易理解。对于 N b i t Nbit Nbit 无符号数其表示的数据范围是 [ 0 , 2 N − 1 ] [0, 2^N-1] [0,2N−1]。移码的特性在于在无符号数的基础上添加了一个 b i a s bias bias 偏移量。其表示的范围变为 [ − b i a s , 2 N − 1 − b i a s ] [-bias,\ 2^N-1-bias] [−bias, 2N−1−bias]。直观来说移码用 a b i a s abias abias 的二进制序列来存储 a a a 的值。其规律如下图所示 移码最直观的特点越小的数字其二进制表示下的无符号数也越小。这为浮点数比较提供了方便。 对于 N b i t Nbit Nbit 表示的移码为了保持移码表示的正负数的数量基本一致其偏移量一般取值为 2 N − 1 − 1 2^{N-1}-1 2N−1−1。对于 8 b i t 8bit 8bit一般的便宜量取值为 127 127 127。这也是 I E E E 754 IEEE754 IEEE754 标准的取值。上方未标明 b i a s bias bias 的取值但可观察到 b i a s bias bias 为 3 3 3。 注课程 C S 61 C CS61C CS61C 在数据表示课程中的移码把 b i a s bias bias 理解为负数例如取偏移量为 − 3 -3 −3而获得表示值的过程变为其无符号数加上 b i a s bias bias。这和我们的 b i a s bias bias 取正获取到真值的过程为无符号数减掉 b i a s bias bias 异曲同工。加负数和减掉正数的区别。标准中为我们理解的 b i a s bias bias 取正值。 阶码的移码表示 阶码用 8 8 8 位表示由于每一个符合标准的小数都必须经过规格化当阶码不相等时则比较阶码阶码相等再去比较尾数。此时为了在没有特定浮点数硬件的机器上支持浮点数例如使用整数比较指令对浮点数进行排序标准制定者对阶码使用移码表示。 若使用补码表示那么当阶码为负数时其二进制序列表示的无符号整数比阶码为正数时更大例如 32 b i t 32bit 32bit 的 − 1 -1 −1 和 1 1 1 用补码表示分别为 0 x 11111111 0x11111111 0x11111111 和 0 x 00000001 0x00000001 0x00000001。 设计者选择移码来表示阶码。为 32 b i t 32bit 32bit 的单精度浮点数中 8 b i t 8bit 8bit 移码选择的 b i a s bias bias 偏移量为 127 127 127。其余长度下浮点数各字段长度如下表所示 我们知道按照 b i a s bias bias 为 127 127 127 来计算其移码可以表示的范围是 [ − 127 , 128 ] [-127, 128] [−127,128]区间两个端点 − 127 -127 −127 对应的阶码二进制为 8 8 8 位全 0 0 0 128 128 128 对应阶码二进制为 8 8 8 位全 1 1 1这两个端点在标准中都有特殊意义故在表格中没有他们。 IEEE754中的特殊点 我们知道 I E E E 754 IEEE754 IEEE754 标准中规定了阶码的表示值的有效范围为 [ − 126 , 127 ] [-126, 127] [−126,127] 其两个端点的特殊情况以及尾数的取值的具体意义如下表所示 阶码为 0 0 0尾数为 0 0 0表示数字 0 0 0。 阶码为 0 0 0尾数不为 0 0 0表示非规格化小数。 阶码的范围 [ 1 , 254 ] [1, 254] [1,254] 对应表示值范围为 [ − 126 , 127 ] [-126, 127] [−126,127] 。无特殊意义正常表示浮点数。 阶码为 255 255 255尾数为 0 0 0表示无穷大符号位的正负作为正负无穷大的区分。 阶码为 255 255 255尾数不为 0 0 0表示 N o t a n u m b e r ( N a N ) Not \ a \ number(NaN) Not a number(NaN) 正式介绍这几种情况之前先给出一个初步不全面的浮点数的表示范围。 最小正数数符为正阶码最小 − 126 -126 −126尾数最小 0 0 0。其表示的浮点数为 1.0 ∗ 2 − 126 ≈ 1.1754 ∗ 1 0 − 38 1.0*2^{-126} \approx 1.1754*10^{-38} 1.0∗2−126≈1.1754∗10−38 最大正数数符为正阶码最大 127 127 127尾数最大 23 b i t 23bit 23bit 全 1 1 1其表示的浮点数为 ( 1 0.5 . . . 2 − 23 ) ∗ 2 127 ( 2 − 2 − 23 ) ∗ 2 127 ≈ 3.4028235 ∗ 1 0 38 (10.5...2^{-23})*2^{127}(2-2^{-23})*2^{127} \approx 3.4028235*10^{38} (10.5...2−23)∗2127(2−2−23)∗2127≈3.4028235∗1038 最小负数数符为负阶码最大 127 127 127尾数最大 23 b i t 23bit 23bit 全 1 1 1其表示的浮点数为 ( − 1 ) ∗ ( 1 0.5 . . . 2 − 23 ) ∗ 2 127 − ( 2 − 2 − 23 ) ∗ 2 127 ≈ − 3.4028235 ∗ 1 0 38 (-1)*(10.5...2^{-23})*2^{127}-(2-2^{-23})*2^{127} \approx -3.4028235*10^{38} (−1)∗(10.5...2−23)∗2127−(2−2−23)∗2127≈−3.4028235∗1038 最大负数数符为负阶码最小 − 126 -126 −126尾数最小 0 0 0其表示的浮点数为 − 1.0 ∗ 2 − 126 ≈ − 1.1754 ∗ 1 0 − 38 -1.0*2^{-126} \approx -1.1754*10^{-38} −1.0∗2−126≈−1.1754∗10−38 用数轴表示其范围如下所示 两个0 对于除了 0 0 0 之外的小数规格化之后的尾数 s i g n i f i c a n d significand significand 范围永远在 ( 0 , 1 ) (0,1) (0,1) 之间。由于 0 0 0 的小数表示没有小数点左侧的 1 1 1 标准规定阶码和尾数为 0 0 0 用于表示数字 0 0 0。注意到符号位可以为 1 1 1表示负数。所以我们有两个 0 0 0。 32 b t i 32bti 32bti 全 0 0 0 表示 0 0 0符号位为 1 1 1其余全 0 0 0 表示 − 0 -0 −0。但他们都是 0 0 0。经过下图程序验证 0 − 0 0-0 0−0。 #include iostream #include cstdio union num{float f_num;int32_t field; }; int main(){std::couthello,worldstd::endl;std::coutsizeof(float)sizeof(float)std::endl;num f1;f1.field0;num f2;f2.field 0x80000000;std::coutf1 f1.f_numstd::endl;std::coutf2 f2.f_numstd::endl;if(f1.f_num f2.f_num)std::cout0 0x80000000std::endl;else std::cout0 ! 0x80000000 std::endl;return 0; }环境为 64 b i t w i n d o w s 64bit \ windows 64bit windows下 v s c o d e m i n g w 64 vscodemingw64 vscodemingw64 时程序输出如下图所示 另外当所有位置全 0 0 0 时按照浮点数公式的严格定义下其表示的数字应该为 1.0 ∗ 2 0 − 127 2 − 127 1.0*2^{0-127}2^{-127} 1.0∗20−1272−127 不为 0 0 0 但无限接近于 0 0 0 下面我们会知道阶码 0 0 0 表示的非规格化数不能按照规格化的计算方式来计算其表示的值标准则规定全 0 0 0 表示 0 0 0。 非规格化数字 根据数轴我们知道正常情况之下标准能够表示的最小正数和最大正数为 2 − 126 2^{-126} 2−126 和 − 2 − 126 -2^{-126} −2−126 。此时我们想要表示更小的非 0 0 0 小数则会超过标准阶码的表示范围引发下溢。从 0 0 0 到 2 − 126 2^{-126} 2−126 之间没有内容无法表示。 此时为了减小下溢的概率标准规定阶码为0尾数不为0则表示非规格化数字其指数默认为-126。其表示的小数计算公式变为 ( − 1 ) S ∗ ( s i g n i f i c a n d ) ∗ 2 − 126 \color{red}(-1)^S*(significand)*2^{-126} (−1)S∗(significand)∗2−126 。其中按照移码的规则阶码为0表示值为 − 127 -127 −127但标准规定非规格化数字的阶码默认为 − 126 -126 −126 不变所有非规格化数字阶码全 0 0 0 一样。 此时我们能够表示的最小正数变为数符为正阶码为 0 0 0尾数为 1 1 1其表示的值为 2 − 23 ∗ 2 − 126 2 0 ∗ 2 − 149 2 − 149 2^{-23}*2^{-126}2^0*2^{-149}2^{-149} 2−23∗2−12620∗2−1492−149 非规格化数能够表示的下一个数字数符为正阶码为 0 0 0尾数为 2 2 2其二进制序列为 0 b 00000000000000000000010 0b00000000000000000000010 0b00000000000000000000010其表示的值为 2 − 22 ∗ 2 − 126 2 − 148 2 1 ∗ 2 − 149 2^{-22}*2^{-126}2^{-148}2^1*2^{-149} 2−22∗2−1262−14821∗2−149 非规格化数能够表示的下一个数字数符为正阶码为 0 0 0尾数为 3 3 3其二进制序列为 0 b 00000000000000000000011 0b00000000000000000000011 0b00000000000000000000011其表示的值为 ( 2 − 22 2 − 23 ) ∗ 2 − 126 2 − 148 2 − 149 ( 2 0 2 1 ) ∗ 2 − 149 (2^{-22}2^{-23})*2^{-126}2^{-148}2^{-149}(2^02^1)*2^{-149} (2−222−23)∗2−1262−1482−149(2021)∗2−149 … … … … 非规格化数能够表示的最后一个数字数符为正阶码为 0 0 0尾数为全 1 1 1其二进制序列为 0 b 11111111111111111111111 0b11111111111111111111111 0b11111111111111111111111其表示的值为 ( 2 − 1 . . . 2 − 22 2 − 23 ) ∗ 2 − 126 2 − 127 . . . 2 − 148 2 − 149 ( 2 22 2 21 . . . 2 1 2 0 ) ∗ 2 − 149 (2^{-1}...2^{-22}2^{-23})*2^{-126}2^{-127}...2^{-148}2^{-149}(2^{22}2^{21}...2^12^0)*2^{-149} (2−1...2−222−23)∗2−1262−127...2−1482−149(222221...2120)∗2−149 另外从另一方面考虑这个结果 ( 2 − 1 . . . 2 − 22 2 − 23 ) ∗ 2 − 126 ( 1 − 2 − 23 ) ∗ 2 − 126 2 − 126 − 2 − 149 (2^{-1}...2^{-22}2^{-23})*2^{-126}(1-2^{-23})*2^{-126}2^{-126}-2^{-149} (2−1...2−222−23)∗2−126(1−2−23)∗2−1262−126−2−149 规格化数能够表示的第一个数字数符为正阶码二进制为 0 b 00000001 0b00000001 0b00000001尾数为全 0 0 0 其表示的值为 1.0 ∗ 2 ∗ 1 − 127 2 − 126 1.0*2*{1-127}2^{-126} 1.0∗2∗1−1272−126 此时尾数加 1 1 1表示的小数值加 2 − 149 2^{-149} 2−149。换一种理解方式为从 0 0 0 到 2 − 126 2^{-126} 2−126 之间的步长为 2 − 149 \color{red}2^{-149} 2−149。尾数从全 0 0 0 到全 1 1 1一共 2 23 2^{23} 223 种取值我们理解为区间分做 2 23 2^{23} 223 份。具体见下表。 数符阶码尾数真值00b000000000b00000000000000000000000000b000000000b00000000000000000000001 2 − 149 2^{-149} 2−14900b000000000b00000000000000000000010 2 ∗ 2 − 149 2*2^{-149} 2∗2−14900b00000000… …… …00b000000000b11111111111111111111111 2 − 126 − 2 − 149 2^{-126}-2^{-149} 2−126−2−149 而浮点数最大值能够表示到 3.4 ∗ 1 0 38 3.4*10^{38} 3.4∗1038一直保持这么小的步长必然不行。 正常浮点数 书接上文我们将揭示为什么浮点数能够表示数据范围如此之大重点关注每次阶码加 1 1 1 之后区间的两个端点和步长的变化。 阶码为 1 1 1的规格化数能够表示的第二个数字数符为正阶码二进制为 0 b 00000001 0b00000001 0b00000001尾数为 1 1 1 其表示的值为 ( 1.0 2 − 23 ) ∗ 2 1 − 127 2 − 126 2 − 149 (1.02^{-23})*2^{1-127}2^{-126}2^{-149} (1.02−23)∗21−1272−1262−149 … … 阶码为 1 1 1 的规格化数能够表示的最后一个数字数符为正阶码二进制为 0 b 00000001 0b00000001 0b00000001尾数为全 1 1 1 其表示的值为 ( 1.0 2 − 1 . . . 2 − 23 ) ∗ 2 1 − 127 2 − 126 2 − 127 . . . 2 − 149 (1.02^{-1}...2^{-23})*2^{1-127}2^{-126}2^{-127}...2^{-149} (1.02−1...2−23)∗21−1272−1262−127...2−149。 阶码为 2 2 2 的规格化数能够表示的第一个数字数符为正阶码二进制为 0 b 00000010 0b00000010 0b00000010尾数为 0 0 0 其表示的值为 ( 1.0 ) ∗ 2 2 − 127 2 − 125 (1.0)*2^{2-127}2^{-125} (1.0)∗22−1272−125 此时从 2 − 126 2^{-126} 2−126 到 2 − 125 2^{-125} 2−125 之间步长仍旧为 2 − 149 \color{red}2^{-149} 2−149区间分做 2 23 2^{23} 223 份。 此时完善表格如下 数符阶码尾数真值00b000000000b00000000000000000000000000b000000000b00000000000000000000001 2 − 149 2^{-149} 2−14900b000000000b00000000000000000000010 2 ∗ 2 − 149 2*2^{-149} 2∗2−14900b00000000… …… …00b000000000b11111111111111111111111 2 − 126 − 2 − 149 2^{-126}-2^{-149} 2−126−2−14900b000000010b00000000000000000000000 2 − 126 2^{-126} 2−12600b000000010b00000000000000000000001 2 − 126 2 − 149 2^{-126}2^{-149} 2−1262−14900b000000010b00000000000000000000010 2 − 126 2 ∗ 2 − 149 2^{-126}2*2^{-149} 2−1262∗2−14900b00000001… …… …00b000000010b11111111111111111111111 2 − 125 − 2 − 149 2^{-125}-2^{-149} 2−125−2−14900b000000100b00000000000000000000000 2 − 125 2^{-125} 2−125 阶码为 2 2 2 的规格化数能够表示的第二个数字数符为正阶码二进制为 0 b 00000010 0b00000010 0b00000010尾数为 1 1 1 其表示的值为 ( 1.0 2 − 23 ) ∗ 2 2 − 127 2 − 125 2 0 ∗ 2 − 148 (1.02^{-23})*2^{2-127}2^{-125}2^0*2^{-148} (1.02−23)∗22−1272−12520∗2−148 … … 阶码为 2 2 2 的规格化数能够表示的最后一个数字数符为正阶码二进制为 0 b 00000010 0b00000010 0b00000010尾数为全 1 1 1 其表示的值为 ( 1.0 2 − 1 . . . 2 − 23 ) ∗ 2 2 − 127 2 − 125 2 − 127 . . . 2 − 148 (1.02^{-1}...2^{-23})*2^{2-127}2^{-125}2^{-127}...2^{-148} (1.02−1...2−23)∗22−1272−1252−127...2−148。 阶码为3的规格化数能够表示的第一个数字数符为正阶码二进制为 0 b 00000011 0b00000011 0b00000011尾数为 0 0 0 其表示的值为 ( 1.0 ) ∗ 2 3 − 127 2 − 124 (1.0)*2^{3-127}2^{-124} (1.0)∗23−1272−124 此时从 2 − 125 2^{-125} 2−125 到 2 − 124 2^{-124} 2−124 之间步长已经变为 2 − 148 \color{blue}2^{-148} 2−148。 此时完善表格如下 数符阶码尾数真值00b000000000b00000000000000000000000000b000000000b00000000000000000000001 2 − 149 2^{-149} 2−14900b000000000b00000000000000000000010 2 ∗ 2 − 149 2*2^{-149} 2∗2−14900b00000000… …… …00b000000000b11111111111111111111111 2 − 126 − 2 − 149 2^{-126}-2^{-149} 2−126−2−14900b000000010b00000000000000000000000 2 − 126 2^{-126} 2−12600b000000010b00000000000000000000001 2 − 126 2 − 149 2^{-126}2^{-149} 2−1262−14900b000000010b00000000000000000000010 2 − 126 2 ∗ 2 − 149 2^{-126}2*2^{-149} 2−1262∗2−14900b00000001… …… …00b000000010b11111111111111111111111 2 − 125 − 2 − 149 2^{-125}-2^{-149} 2−125−2−14900b000000100b00000000000000000000000 2 − 125 2^{-125} 2−12500b000000100b00000000000000000000001 2 − 125 2 − 148 2^{-125}2^{-148} 2−1252−14800b000000100b00000000000000000000010 2 − 125 2 ∗ 2 − 148 2^{-125}2*2^{-148} 2−1252∗2−14800b00000010… …… …00b000000100b11111111111111111111111 2 − 124 − 2 − 148 2^{-124}-2^{-148} 2−124−2−14800b000000110b00000000000000000000000 2 − 124 2^{-124} 2−124 … … … … 中间省略掉大部分我们跳到阶码为 127 127 127二进制表示为 0 b 01111111 0b01111111 0b01111111其表示值为 0 0 0 。读者可以猜测此时区间两端点为多少 阶码为127的规格化数能够表示的第一个数字数符为正阶码二进制为 0 b 01111111 0b01111111 0b01111111尾数为 0 0 0 其表示的值为 ( 1.0 ) ∗ 2 127 − 127 2 0 1 (1.0)*2^{127-127}2^01 (1.0)∗2127−127201。 阶码为 127 127 127 的规格化数能够表示的第二个数字数符为正阶码二进制为 0 b 01111111 0b01111111 0b01111111尾数为 1 1 1 其表示的值为 ( 1.0 2 − 23 ) ∗ 2 127 − 127 2 0 2 − 23 1 2 − 23 (1.02^{-23})*2^{127-127}2^02^{-23}12^{-23} (1.02−23)∗2127−127202−2312−23。 … … 阶码为 127 127 127 的规格化数能够表示的最后一个数字数符为正阶码二进制为 0 b 01111111 0b01111111 0b01111111尾数为全 1 1 1 其表示的值为 ( 1.0 2 − 1 . . . 2 − 23 ) ∗ 2 127 − 127 2 0 2 − 1 . . . 2 − 23 (1.02^{-1}...2^{-23})*2^{127-127}2^{0}2^{-1}...2^{-23} (1.02−1...2−23)∗2127−127202−1...2−23。 阶码为128的规格化数能够表示的第一个数字数符为正阶码二进制为 0 b 10000000 0b10000000 0b10000000尾数为 0 0 0 其表示的值为 ( 1.0 ) ∗ 2 128 − 127 2 1 2 (1.0)*2^{128-127}2^{1}2 (1.0)∗2128−127212 此时从 1 1 1 到 2 2 2 之间步长已经变为 2 − 23 \color{blue}2^{-23} 2−23。还是发现不了规律我们继续看表 数符阶码尾数真值00b000000000b00000000000000000000000000b000000000b00000000000000000000001 2 − 149 2^{-149} 2−14900b000000000b00000000000000000000010 2 ∗ 2 − 149 2*2^{-149} 2∗2−1490… …… …… …00b011111110b00000000000000000000000 1 1 100b1111111… …… …00b011111110b11111111111111111111111 1 − 2 23 1-2^{23} 1−22300b100000000b00000000000000000000000 2 2 2 … … … … 中间再省略掉大部分我们跳到阶码为 150 150 150二进制表示为 0 b 10010110 0b10010110 0b10010110其表示值为 23 23 23 。读者可以猜测此时步长为多少 阶码为 150 150 150 的规格化数能够表示的第一个数字数符为正阶码二进制为 0 b 10010110 0b10010110 0b10010110尾数为 0 0 0 其表示的值为 ( 1.0 ) ∗ 2 150 − 127 2 23 (1.0)*2^{150-127}2^{23} (1.0)∗2150−127223。 阶码为 150 150 150 的规格化数能够表示的第二个数字数符为正阶码二进制为 0 b 01111111 0b01111111 0b01111111尾数为 1 1 1 其表示的值为 ( 1.0 2 − 23 ) ∗ 2 150 − 127 2 23 1 (1.02^{-23})*2^{150-127}2^{23}1 (1.02−23)∗2150−1272231。 … … 阶码为 150 150 150 的规格化数能够表示的最后一个数字数符为正阶码二进制为 0 b 01111111 0b01111111 0b01111111尾数为全 1 1 1 其表示的值为 ( 1.0 2 − 1 . . . 2 − 23 ) ∗ 2 150 − 127 2 23 2 22 . . . 2 0 2 24 − 1 (1.02^{-1}...2^{-23})*2^{150-127}2^{23}2^{22}...2^{0}2^{24}-1 (1.02−1...2−23)∗2150−127223222...20224−1。 阶码为 151 151 151 的规格化数能够表示的第一个数字数符为正阶码二进制为 0 b 10000000 0b10000000 0b10000000尾数为 0 0 0 其表示的值为 ( 1.0 ) ∗ 2 151 − 127 2 24 (1.0)*2^{151-127}2^{24} (1.0)∗2151−127224 此时从区间 2 23 2^{23} 223 到 2 24 2^{24} 224 之间步长已经变为 1 \color{blue}1 1。 a m a z i n g ! ! ! \color{red}amazing ! ! ! amazing!!! 此时再问一个问题阶码为 151 151 151 时步长和区间两端点各为多少分别是 2 2 2 和 [ 2 24 , 2 25 ] [2^{24}, 2^{25}] [224,225] … … … … 阶码为 254 254 254 时其表示值为 127 127 127 此时步长为 2 104 2^{104} 2104区间端点变为 [ 2 127 , ∞ ] [2^{127}, ∞] [2127,∞]无穷大随后详细解释。 至此我们已经揭示了规律阶码从1开始阶码每次加1步长乘2区间两端点乘以2。 另外区间内永远分作 2 23 2^{23} 223 份。这也是为什么浮点数能够表示 3.4 ∗ 1 0 38 3.4*10^{38} 3.4∗1038 这么大的数字。 无穷大 书接上文。标准规定阶码为 255 255 255尾数为 0 0 0表示无穷大。数符用来区分正无穷和负无穷。 我们知道按照移码的规律和标准规定阶码为 254 254 254表示值 127 127 127 已经为 32 b i t 32bit 32bit 单精度浮点数能够表示的最大阶码。 阶码为 254 254 254 的规格化数能够表示的最后一个数字数符为正阶码二进制为 0 b 11111110 0b11111110 0b11111110尾数为全 1 1 1 其表示的值为 ( 1.0 2 − 1 . . . 2 − 23 ) ∗ 2 254 − 127 2 127 2 126 . . . 2 104 (1.02^{-1}...2^{-23})*2^{254-127}2^{127}2^{126}...2^{104} (1.02−1...2−23)∗2254−12721272126...2104。 此时再进一步浮点数能够表示的下一个数应当是阶码为255的规格化数能够表示的第一个数。即阶码为 255 255 255尾数为 0 0 0。标准将其规定为无穷大。非常合理。 NaN 无穷大之后再进一步标准规定阶码为 255 255 255尾数非 0 0 0 为 N o t a N u m b e r Not \ a \ Number Not a Number。 读者可通过一些协商/协议/标准来自定义其 N a N NaN NaN 具体类型例如尾数为 1 1 1表示对负数做平方根尾数为 2 2 2表示除以 0 0 0 的非法操作等等等。 浮点数简单举例 对于一个浮点数二进制序列 0 b 1 10000001 11100000000000000000000 0b1 \ 10000001 \ 11100000000000000000000 0b1 10000001 11100000000000000000000计算其表示值为 ( − 1 ) ∗ ( 1.0 0.5 0.25 0.125 ) ∗ 2 129 − 127 − 7.5 (-1)*(1.00.50.250.125)*2^{129-127}-7.5 (−1)∗(1.00.50.250.125)∗2129−127−7.5 如何表示 1 / 3 1/3 1/3 1 / 3 0.333333333... 0.25 0.0625 0.015625 . . . 1 / 4 1 / 16 1 / 64 1 / 256 . . . 2 − 2 2 − 4 2 − 8 . . . 1/3 0.333333333...0.250.06250.015625...1/41/161/641/256...2^{-2}2^{-4}2^{-8}... 1/30.333333333...0.250.06250.015625...1/41/161/641/256...2−22−42−8... 二进制小数表示为 0.010101010101.. . 2 ∗ 2 0 0.010101010101..._{2} *2^0 0.010101010101...2​∗20规格化之后变为 1.01010101.. . 2 ∗ 2 − 2 1.01010101..._2 *2^{-2} 1.01010101...2​∗2−2。此时转为 32 b i t 32bit 32bit 标准表示数符为0阶码为 − 2 127 125 0 b 01111101 -21271250b01111101 −21271250b01111101尾数为 0 b 01010101010101010101010 0b0101 0101 0101 0101 0101 010 0b01010101010101010101010。 综上 1 / 3 1/3 1/3 的浮点数表示为 0 b 0 01111101 01010101010101010101010 0b0 \ 01111101 \ 01010101010101010101010 0b0 01111101 01010101010101010101010 浮点数一些其余特性 浮点数计算不符合结合律 假设 x 1.5 ∗ 1 0 38 x1.5*10^{38} x1.5∗1038 y − 1.5 ∗ 1 0 38 y-1.5*10^{38} y−1.5∗1038 z 1 z1 z1 x y z xyz xyz 的结果和 x z y xzy xzy 的结果不一致。 验证程序如下所示 #include iostreamint main(){float f11.5e38,f2-1.5e38,f31.0;std::cout(1.5e38(-1.5e38))1.0 f1f2f3std::endl;std::cout(1.5e381.0)(-1.5e38) f1f3f2std::endl;return 0; }程序输出如下所示 主要问题在于浮点数的加法执行流程粗略来讲为首先要对两个小数统一阶码阶码统一之后才可以尾数相加尾数相加之后再重新规格化。这其中 23 b i t 23bit 23bit 精度的限制必然会导致位的缺失。 浮点数舍入规则 既然尾数位数有限必然要有舍入的规则来确定多余的位如何处理。浮点数的舍入规则为舍入到偶数。 对于普通小数例如2.4则四舍五入为22.6则四舍五入为3。对于中间位置例如2.5舍入为23.5舍入为4。 上述规则是在十进制下的二进制下同理以定点小数为例 11. 1 2 11.1_2 11.12​舍入时考虑到前方为 1 1 2 11_2 112​为奇数则舍入为 10 0 2 100_2 1002​。 10. 1 2 10.1_2 10.12​ 舍入时则直接丢弃小数部分舍入为 1 0 2 10_2 102​ 。下标 2 2 2 表示二进制。 浮点数与整数之间的相互转换 考虑以下问题一个整数强制类型转换为浮点数再转为整数是否还和原来相等 uint32_t i; if(i (uint32_t)(float)i){printf(true!); }答案是不全部相等。根据上文的区间分析我们知道当阶码为 151 151 151 时其表示值为 24 24 24此时区间端点为 [ 2 24 , 2 25 ] [2^{24}, 2^{25}] [224,225]区间步长为 2 2 2。此时我们就定义整数初值为 2 24 1 2^{24}1 2241按照此时 2 2 2 的步长浮点数刚好无法表示此时转换必然存在位丢失情况而C语言中的浮点数到整数的类型转换仅仅是丢弃全部小数只取整数 2 24 16 , 777 , 216 2^{24}16,777,216 22416,777,216。 程序验证如下所示 #include iostream int main(){float f103.2f,f113.5f,f123.9f;std::cout(uint32_t)3.2 (uint32_t)f10std::endl;std::cout(uint32_t)3.5 (uint32_t)f11std::endl;std::cout(uint32_t)3.9 (uint32_t)f12std::endl;std::cout-------------------------std::endl;uint32_t target(124)1;std::cout(float)(124)1 ((float)target)std::endl;std::cout(uint32_t)(float)(124)1 ((uint32_t)(float)target)std::endl;return 0; }程序输出结果如下图所示 正如我们猜测的结果一样。 考虑另外问题一个浮点数强制类型转换为整数再转为浮点数是否还和原来相等 float f; if(f (float)(uint32_t)f){printf(true!); }当然不等。考虑 1.5 1.5 1.5转为整数后变为 1 1 1浮点数可以表示 1 1 1。故转换之后结果变为 1 1 1。 程序验证如下 int main(){float f11.5f;std::cout(float)(uint32_t)(1.5) (float)((uint32_t)(f1))std::endl;return 0; }结果输出如下图所示 好 总结 完结撒花你已经完全了解计算机中小数表示了。
http://www.zqtcl.cn/news/845294/

相关文章:

  • 做羊毛毡的网站电子商务网站建设品牌
  • 用vue做商城网站常用的js教做发型的网站
  • 江西省寻乌县建设局网站广州网站建设一般多少钱
  • 做网站公司郑州郑州的网站建设公司哪家好网站开发word
  • 网页转向功能网站wordpress搭建小说站
  • 北京华夏建设有限公司网站wordpress建站安全吗
  • 怎样做电子商务网站直接通过ip访问网站
  • 白沟17网站一起做网店有啥方法下载wordpress主题
  • 找人做网站毕业设计用于做网站头的图片
  • 黄埔做网站江西省建设工程造价管理局网站
  • 适合网站开发的框架网盘视频直接做网站
  • wordpress菜谱网站网站服务公司
  • 跳转网站代码互联网平台构建怎么写
  • 服务器网站建设维护uemo网站源码
  • 浏览器如何做购物网站百度快照提交入口
  • 网站建设的主要步骤有哪些金华网站建设平台
  • 扁平化网站布局稷山网站制作
  • 做画找图网站包装策划与设计专业
  • 适合大学生做的兼职网站深圳企业名录大全
  • 电脑做网站用什么软件培训心得体会2000字
  • 手机网站开发公司哪家最专业html5商业网站开发北大青鸟
  • 做爰全过程教育网站建筑工程公司名字起名大全
  • 如何作做网站网站建设需要掌握什么技术
  • 广州网站建设推广公司做网站怎么合并单元格
  • 网站建设策划书的编制怎样建网站域名
  • 公司做网站的费用怎么记账网站源码html
  • 网站流量数据东莞松山湖华为招聘信息
  • 跨境电商一站式服务平台wordpress用旧的编辑器
  • 上海外贸网站推广方法爱站关键词
  • 网站页面框架设计企业建设流程