草庐IT

IEEE浮点数向偶数舍

Az1r 2023-03-28 原文

CSAPP

​ 向偶数舍入初看上去好像是个相当随意的目标——有什么理由偏向取偶数呢?为什么不始终把位于两个可表示的值中间的值都向上舍入呢?使用这种方法的一个问题就是很容易假想到这样的情景:这种方法舍入一组数值,会在计算这些值的的平均数中引入统计偏差。我们采用这种方法舍入一组数的平均值将比这些数本身旳平均值略高一些。相反,如果我们总是把两个可表示值中间的数字向下舍入,那么舍入出的一组数的平均值将比这些数本身的平均值略低一些。向偶数舍入在大多数现实情况中避免了这种统计偏差。在50%的时间里,它将向上舍入,而在50%的时间里,它将向下舍入。

如何向偶数舍入

要点

  • 只有在两个可表示的数中间的数才会进行偶数舍入
  • 其余情况为,舍入到靠近的那个可表示的数

十进制

舍入到小数点后两位

  • 1.2349999舍入为1.23 1.2350001舍入为1.24
  • 因为它们不是1.231.24的正中间

  • 1.2350000 舍入为1.24 1.2450000舍入为1.24
  • 因为前者处于1.231.24的正中间,后者处于1.241.25的正中间,且4为偶数

二进制

舍入到小数点后两位

两个二进制数的正中间

  1. 现在是舍入到小数点后两位,那么我们看从小数点后三位开始的数字,就叫它多余数字
  2. 多余数字正好为100000000...时,它的大小是正好是上一位为1所代表的数的一半,也就是说,在正中间
  3. 多余数字第一位为0,比如01001001000...,它小于中间值,所以向下舍入
  4. 多余数字第一位为1,且其他位还有1,比如10000010001...,它大于中间值,所以向上舍入

二进制小数的偶数

我们将最低有效位的值为0认为是偶数,1认为是奇数

  • 10.00011舍入为10.00 10.00110舍入为10.01
  • 因为它们不是10.0010.01的中间值

  • 10.11100舍入为11.00 10.10100舍入为10.10
  • 它们的多余数字均为中间值,所以进行向偶数舍入
  • 前者最低有效位为1,则进1,使之为0
  • 后者最低有效位为0,则舍去多余数字即可
舍入前 1.01011 1.01100 1.01101 1.01110 1.01111 1.10000 ... 1.10100
舍入后 1.01000 1.10000 1.10000 1.10000 1.10000 1.10000 ... 1.10000
状态 向下 向偶数 向上 向上 向上 向下 ... 向偶数

有关IEEE浮点数向偶数舍的更多相关文章

  1. ruby-on-rails - ruby on rails 模型验证中的浮点精度 - 2

    我正在尝试使用正则表达式验证美元金额:^[0-9]+\.[0-9]{2}$这工作正常,但每当用户提交表单并且美元金额以0(零)结尾时,ruby(或rails?)将0砍掉。所以500.00变成500.0,因此正则表达式验证失败。有没有办法让ruby​​/rails保持用户输入的格式,而不管尾随零? 最佳答案 我假设您的美元金额是小数类型。因此,用户在字段中输入的任何值在保存到数据库之前都会从字符串转换为适当的类型。验证适用于已转换为数字类型的值,因此在您的情况下,正则表达式并不是真正合适的验证过滤器。不过,您有几种可能性可以解决这个问

  2. ruby-on-rails - 浮点乘法的 Ruby 奇怪问题 - 2

    有没有人用ruby​​解决这个问题:假设我们有:a=8.1999999我们想将它四舍五入为2位小数,即8.20,然后乘以1,000,000得到8,200,000我们是这样做的;(a.round(2)*1000000).to_i但是我们得到的是8199999,为什么?奇怪的是,如果我们乘以1000、100000或10000000而不是1000000,我们会得到正确的结果。有人知道为什么吗?我们正在使用ruby​​1.9.2并尝试使用1.9.3。谢谢! 最佳答案 每当你在计算中得到时髦的数字时使用bigdecimalrequire'bi

  3. Ruby 浮点精度 - 2

    据我了解,Ruby(1.9.2)float的精度为15位十进制数字。因此,我希望将floatx舍入到小数点后15位将等于x。对于此计算,情况并非如此。x=(0.33*10)x==x.round(15)#=>false顺便说一句,四舍五入到16位返回true。你能给我解释一下吗? 最佳答案 部分问题是0.33在底层格式中没有精确的表示,因为它不能用一系列1/2n项来表示。因此,当它乘以10时,乘以的数字与0.33略有不同。就此而言,3.3也没有精确表示。第一部分当数字没有精确的10进制表示时,在转换尾数中有信息的最低有效位时会有余数。

  4. ruby 浮点错误 - 2

    有人可以解释为什么在这里乘以100得到的结果不太准确,而两次乘以10得到的结果更准确吗?±%scLoadingdevelopmentenvironment(Rails3.0.1)>>129.95*10012994.999999999998>>129.95*101299.5>>129.95*10*1012995.0 最佳答案 如果您使用限制为53位有效位的double二进制手动进行计算,您将看到发生了什么:129.95=1.0000001111100110011001100110011001100110011001100110x2^7

  5. ruby - 在 Ruby 中将唯一的种子字符串转换为随机但确定的浮点值 - 2

    我在概念上遇到了困难。基本上,我需要接受一些任意的唯一字符串,并能够将其转换为规范化的浮点值。输出浮点值是什么并不重要,只要相同的字符串输入总是产生相同的规范化浮点输出即可。所以这是一个哈希算法,对吗?我熟悉SHA1或MD5,这似乎类似于密码散列,正确密码的结果相同。但是我相信那些方法会输出字符串。我没有得到的是如何将SHA1或MD5的结果转换为一致的浮点值。#Goaldefstring_to_float(seed_string)#...endstring_to_float('abc-123')#=>0.15789string_to_float('abc-123')#=>0.15789

  6. Ruby - 将字符串转换为浮点返回 0.0 - 2

    在一个变量中存储了这个值:$10.00我需要得到这个10.00我已尝试将此值转换为float:new_price='%.2f'%(price.to_f)但我只得到0.0。这有什么问题?我也试过了price=price.stripprice[0]=""new_price='%.2f'%(price.to_f)但即使这样也没有帮助我......哪里有问题?谢谢 最佳答案 您需要先删除$。整个事情是这样的:'%.2f'%'$10.00'.delete("$").to_f或'%.2f'%'$10.00'[1..-1].to_f如果你喜欢密度

  7. ruby - Ruby 矩阵计算中的浮点错误 - 2

    我正在编写一些涉及查找给定矩阵的特征向量的代码,令我惊讶的是Ruby在简单情况下会产生一些不合理的结果。例如,以下矩阵具有与特征值1关联的特征向量:>m=Matrix[[0r,1/2r,1/2r,1/3r],[0r,0r,1/4r,1/3r],[0r,1/4r,0r,1/3r],[1r,1/4r,1/4r,0r]]Ruby很好地找到了特征值,但是特征向量爆炸了:>m.eigen.eigenvalues[2]=>1.0000000000000009m.eigen.eigenvectors[2]=>Vector[5.957702309312754e+15,5.957702309312748

  8. ruby-on-rails - 确定字符串是否为有效的浮点值 - 2

    有没有一种方法可以简单地检查字符串值是否是有效的浮点值。如果字符串不是数值,则对字符串调用to_f会将其转换为0.0。使用Float()会在传递一个更接近我想要的无效浮点字符串时引发异常,但我不想处理捕获异常。我真正想要的是像nan这样的方法?它确实存在于Float类中,但这无济于事,因为如果不将非数字字符串更改为0.0(使用to_f),则无法将其转换为float。"a".to_f=>0.0"a".to_f.nan?=>falseFloat("a")=>ArgumentError:invalidvalueforFloat():"a"对此是否有简单的解决方案,或者我是否需要编写代码来检查

  9. ruby - Ruby 数组中的奇数(或偶数)条目 - 2

    有没有一种快速的方法来获取Ruby数组中的所有其他条目?奇数或偶数条目值中包含0。我希望能够像这样使用它:array1+=array2.odd_values或putsarray2.odd_values.join("-")例如更新这正是我所追求的,但我确信还有更短的版本。array1.each_with_indexdo|item,index|if(index%2==0)thenarray2.push(item)endend 最佳答案 a=('a'..'z').to_aa.values_at(*a.each_index.select{|

  10. Javascript 嵌套数组返回偶数 - 2

    我正在尝试编写一个函数,它只打印嵌套数组中的偶数。这是我的尝试,它一直返回“未定义”。functionprintEvents(){varnestedArr=[[1,2,3],[4,5,6],[7,8],[9,10,11,12]];for(vari=0;i 最佳答案 如果项目是数组,您可以使用递归方法。您需要将均匀度测试移到for循环中。functionprintEvents(array){vari;for(i=0;i带回调的解决方案functiongetEven(a){if(Array.isArray(a)){a.forEach(g

随机推荐