为什么除法结果会根据强制转换类型而有所不同? (跟进)

2024-02-22

这是这个问题的后续:为什么除法结果会根据强制转换类型而有所不同? https://stackoverflow.com/questions/25703304/why-does-a-division-result-differ-based-on-the-cast-type

快速总结:

byte b1 = (byte)(64 / 0.8f); // b1 is 79
int b2 = (int)(64 / 0.8f); // b2 is 79
float fl = (64 / 0.8f); // fl is 80

问题是:为什么根据演员类型的不同结果会有所不同?在寻找答案时,我遇到了一个无法解释的问题。

var bytes = BitConverter.GetBytes(64 / 0.8f).Reverse(); // Reverse endianness
var bits = bytes.Select(b => Convert.ToString(b, 2).PadLeft(8, '0'));
Console.WriteLine(string.Join(" ", bits));

这会输出以下内容:

01000010 10100000 00000000 00000000

将其分解为 IEEE 754 格式:

0 10000101 01000000000000000000000

Sign:

0 => Positive

指数:

10000101 => 133 in base 10

尾数:

01000000000000000000000 => 0*2^-1 + 1*2^-2 + 0*2^-3 ... = 1/4 = 0.25

十进制表示法:

(1 + 0.25) * 2^(133 - 127) (Subtract single precision bias)

结果正好是 80。那么为什么转换结果会产生不同呢?


我在另一个线程中的回答并不完全正确:实际上,在运行时计算时,(byte)(64 / 0.8f) is 80.罢工>

当施放一个float包含结果64 / 0.8f, to byte在运行时,结果实际上是 80。但是,当转换作为赋值的一部分完成时,情况并非如此:

float f1 = (64 / 0.8f);

byte b1 = (byte) f1;
byte b2 = (byte)(64 / 0.8f);

Console.WriteLine(b1); //80
Console.WriteLine(b2); //79

虽然 b1 包含预期结果,但 b2 关闭。根据反汇编,b2 的赋值如下:

mov         dword ptr [ebp-48h],4Fh 

因此,编译器计算出的结果似乎与运行时的结果不同。但是,我不知道这是否是预期的行为。

EDIT:也许这就是 Pascal Cuoq 所描述的效果:在编译时,C# 编译器使用double来计算表达式。这会导致 79,xxx 被截断为 79(因为双精度数包含足够的精度,因此会导致问题)。
然而,使用浮点数,我们实际上并没有遇到问题,因为浮点“错误”发生在浮点数的范围内。

在运行时,这个也打印 79:

double d1 = (64 / 0.8f);
byte b3 = (byte) d1;
Console.WriteLine(b3); //79

EDIT2:根据 Pascal Cuoq 的要求,我运行了以下代码:

int sixtyfour = Int32.Parse("64");
byte b4 = (byte)(sixtyfour / 0.8f);
Console.WriteLine(b4); //79

结果是79。所以上面所说的编译器和运行时计算出不同结果的说法是不正确的。

EDIT3:将之前的代码更改为(再次归功于 Pascal Cuoq)时,结果为 80:

byte b5 = (byte)(float)(sixtyfour / 0.8f);
Console.WriteLine(b5); //80

但请注意,写入时情况并非如此(结果为 79):

byte b6 = (byte)(float)(64 / 0.8f);
Console.WriteLine(b6); //79

所以这似乎是发生的事情:(byte)(64 / 0.8f)不被评价为float,但评估为double(在将其投射到byte)。这会导致舍入误差(当使用以下方法完成计算时不会发生舍入误差)float)。在转换为 double 之前显式转换为 float(顺便说一句,这被 ReSharper 标记为多余)“解决”了这个问题。但是,当计算在编译时完成时(仅使用常量时可能),显式转换为float似乎被忽略/优化掉了。

TLDR:浮点计算比最初看起来更复杂。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么除法结果会根据强制转换类型而有所不同? (跟进) 的相关文章

  • Qt-Qlist 检查包含自定义类

    有没有办法覆盖加载自定义类的 Qt QList 的比较机制 即在 java 中你只需要重写一个比较方法 我有一个带有我的自定义类模型的 QList QList
  • 从父类调用子类方法

    a doStuff 方法是否可以在不编辑 A 类的情况下打印 B did stuff 如果是这样 我该怎么做 class Program static void Main string args A a new A B b new B a
  • 未解决的包含:“cocos2d.h” - Cocos2dx

    当我在 Eclipse 中导入 cocos2dx android 项目时 我的头文件上收到此警告 Unresolved inclusion cocos2d h 为什么是这样 它实际上困扰着我 该项目可以正确编译并运行 但我希望这种情况消失
  • C++ 子字符串返回错误结果

    我有这个字符串 std string date 20121020 我正在做 std cout lt lt Date lt lt date lt lt n std cout lt lt Year lt lt date substr 0 4 l
  • 如何忽略“有符号和无符号整数表达式之间的比较”?

    谁能告诉我必须使用哪个标志才能使 gcc 忽略 有符号和无符号整数表达式之间的比较 警告消息 gcc Wno sign compare 但你确实应该修复它警告你的比较
  • 将布尔参数传递给 SQL Server 存储过程

    我早些时候问过这个问题 我以为我找到了问题所在 但我没有 我在将布尔参数传递给存储过程时遇到问题 这是我的 C 代码 public bool upload false protected void showDate object sende
  • 在 Visual Studio 2008 上设置预调试事件

    我想在 Visual Studio 中开始调试程序之前运行一个任务 我每次调试程序时都需要运行此任务 因此构建后事件还不够好 我查看了设置的 调试 选项卡 但没有这样的选项 有什么办法可以做到这一点吗 你唯一可以尝试的 IMO 就是尝试Co
  • C#:如何防止主窗体过早显示

    在我的 main 方法中 我像往常一样启动主窗体 Application EnableVisualStyles Application SetCompatibleTextRenderingDefault false Application
  • C 预处理器库

    我的任务是开发源分析工具C程序 并且我需要在分析本身之前预处理代码 我想知道什么是最好的图书馆 我需要一些重量轻 便于携带的东西 与其推出自己的 为什么不使用cpp这是的一部分gcc suite http gcc gnu org onlin
  • Json.NET - 反序列化接口属性引发错误“类型是接口或抽象类,无法实例化”

    我有一个类 其属性是接口 public class Foo public int Number get set public ISomething Thing get set 尝试反序列化Foo使用 Json NET 的类给我一条错误消息
  • 如果使用 SingleOrDefault() 并在数字列表中搜索不在列表中的数字,如何返回 null?

    使用查询正数列表时SingleOrDefault 当在列表中找不到数字时 如何返回 null 或像 1 这样的自定义值 而不是类型的默认值 在本例中为 0 你可以使用 var first theIntegers Cast
  • Qt moc 在头文件中实现?

    是否可以告诉 Qt MOC 我想声明该类并在单个文件中实现它 而不是将它们拆分为 h 和 cpp 文件 如果要在 cpp 文件中声明并实现 QObject 子类 则必须手动包含 moc 文件 例如 文件main cpp struct Sub
  • 不同编程语言中的浮点数学

    我知道浮点数学充其量可能是丑陋的 但我想知道是否有人可以解释以下怪癖 在大多数编程语言中 我测试了 0 4 到 0 2 的加法会产生轻微的错误 而 0 4 0 1 0 1 则不会产生错误 两者计算不平等的原因是什么 在各自的编程语言中可以采
  • 如何将图像路径保存到Live Tile的WP8本地文件夹

    我正在更新我的 Windows Phone 应用程序以使用新的 WP8 文件存储 API 本地文件夹 而不是 WP7 API 隔离存储文件 旧的工作方法 这是我如何成功地将图像保存到 共享 ShellContent文件夹使用隔离存储文件方法
  • 从路径中获取文件夹名称

    我有一些路c server folderName1 another name something another folder 我如何从那里提取最后一个文件夹名称 我尝试了几件事 但没有成功 我只是不想寻找最后的 然后就去休息了 Thank
  • C++ 复制初始化和直接初始化,奇怪的情况

    在继续阅读本文之前 请阅读在 C 中 复制初始化和直接初始化之间有区别吗 https stackoverflow com questions 1051379 is there a difference in c between copy i
  • 需要哪个版本的 Visual C++ 运行时库?

    microsoft 的最新 vcredist 2010 版 是否包含以前的版本 2008 SP1 和 2005 SP1 还是我需要安装全部 3 个版本 谢谢 你需要所有这些
  • 如何让Gtk+窗口背景透明?

    我想让 Gtk 窗口的背景透明 以便只有窗口中的小部件可见 我找到了一些教程 http mikehearn wordpress com 2006 03 26 gtk windows with alpha channels https web
  • 32 位到 64 位内联汇编移植

    我有一段 C 代码 在 GNU Linux 环境下用 g 编译 它加载一个函数指针 它如何执行并不重要 使用一些内联汇编将一些参数推送到堆栈上 然后调用该函数 代码如下 unsigned long stack 1 23 33 43 save
  • x86 上未对齐的指针

    有人可以提供一个示例 将指针从一种类型转换为另一种类型由于未对齐而失败吗 在评论中这个答案 https stackoverflow com questions 544928 reading integer size bytes from a

随机推荐

  • JAX-RS 非常适合实现 REST。在 Java 中使用什么来调用 REST 服务? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 理想情况下 我正在寻找类似 JAX RS 的东西 使用注释来描述我想要调用的服务 但允许调用使用其他技术 不是 JAX RS 实现的 RE
  • javascript(类java)哈希码实现

    以下代码是我对相当通用的 javascript 哈希代码实现的尝试 我计划将此代码与哈希表实现 例如 jshashtable 结合使用 该哈希表实现使用 hashCode 如果为键定义 我尝试严格遵守 java 的数字 字符串和数组的哈希码
  • 何时/为何在 for 循环上使用 map/reduce

    我第一次接触 JavaScript 中的对象操作 我有一个问题 想知道是否有人可以回答 当我想要操作一个对象时 我可以在一些嵌套的 for 循环范围内执行某些操作 但是 JavaScript 中内置了一些函数 例如 map reduce f
  • 在 Wildfly 上激活 JaxbAnnotationModule

    我正在尝试在 Wildfly 8 上设置一个 REST 服务 该服务返回带有自定义枚举值的 JSON 我知道 Wildfy 使用 Jackson 2 3 进行连载 我还知道 当使用 Jackson ObjectMapper 注册 JaxbA
  • leiningen: 缺少超级 pom

    如果我启用 clojure couchdb 或 swank clojure 那么lein deps失败 因为 org apache maven super pom jar 2 0 丢失 dependencies org clojure cl
  • 为什么我的自定义 `::swap` 函数没有被调用?

    这里我写一个代码片段看看是哪个swap会被调用 但结果都不是 什么也没有输出 include
  • iOS,我应该在项目中设置什么体系结构设置?

    对我的应用程序进行一些细微修改并将其加载到最新的 xcode 版本后 我注意到以下设置 我应该删除armv6吗 下拉菜单中的选项显示armv7 armv7s 我应该设置什么 如果你真的不想支持 iPhone3G和更低 不3GS 然后你可以删
  • 在 ios 9.1 中使用什么来代替 UIScreen.mainScreen().applicationFrame 进行 swift ?

    这可能是一个简单的问题 但由于我是初学者 最好问一下 正如标题所说 我应该使用什么来代替UIScreen mainScreen applicationFrame因为它在 9 0 中已被弃用 如果可能的话 如果你能给我提供一个样本或例子 那就
  • 有没有办法用茉莉花验证间谍执行的顺序?

    我有两个对象已被 Jasmine 设置为间谍 spyOn obj spy1 spyOn obj spy2 我需要验证调用spy1在致电之前来spy2 我可以检查它们是否都被调用 expect obj spy1 toHaveBeenCalle
  • 如何使用Java在线下载mp3文件?

    我使用以下方法下载 mp3 文件 http online1 tingclass com lesson shi0529 43 32 mp3 http online1 tingclass com lesson shi0529 43 32 mp3
  • 如何在x86汇编的数据段中写入常量

    我正在编写一个汇编程序 使用 icc 作为汇编器 我需要在数据部分编写一些常量 以便在主程序中进行相对加载 例如以下指令 vmovdqu msg rip ymm0 我现在将数据部分写成这样 data msg 0x00000000 0x010
  • 使用 Swift 将字符串转换为 Int

    该应用程序基本上通过输入初始速度和最终速度以及时间来计算加速度 然后使用公式来计算加速度 但是 由于文本框中的值是字符串 因此我无法将它们转换为整数 IBOutlet var txtBox1 UITextField IBOutlet var
  • 如何管理grails中多个表的分页?

    我的 gsp 页面中有两个表 部分 我需要在它们上实现分页 表 节的每页中的记录数不同 例如 第一个表应每页显示 10 条记录 第二个表 节应每页显示 7 条记录 我使用标签来实现它 当我这样做时 我遇到了很多问题 如下所述 最初 它显示每
  • 设置应用程序图标 (Xcode 7)

    我环顾四周 我发现的其他主题都没有解决我在应用程序图标中遇到的错误 当我尝试运行我的应用程序时 出现错误 名为 AppIcon 的应用程序图标集没有任何适用的内容 我很确定这是因为我没有将 png 文件放在正确的位置 但我不知道将其放在哪里
  • 在 Rails 4 中发送带有远程 true 的表单

    我有一个用于更新图像的表格 该行动有 respond to do format format js format html end 但我收到以下错误 ActionView MissingTemplate Missing template u
  • 使用 For 循环在 Oracle 过程中检索多行

    我正在处理存储过程 我需要检索一组结果并单独处理每个元素 然后返回整个结果 使用 3 个不同的表 我对数据库不太熟悉 但这就是我能想到的 create or replace procedure GET EMP RSLT IS CURSOR
  • 当您收到通用 SoapException:服务器无法处理请求时,如何缩小实际问题的范围。来自MS-CRM 4.0

    我最近开始针对 CRM 4 0 进行编程 并使用 CrmService 发出这些请求 当我发送请求时 我经常在使用的动态实体的某些属性中得到错误的值 当然请求失败了 我拦截异常并记录它 问题是这就是我得到的 System Web Servi
  • Lua 匹配字符串中字符后的所有内容

    我是 Lua 新手 不太了解模式匹配 我试图弄清楚如何匹配冒号后字符串中的所有内容 并将字符串的该部分放入变量中 我在网上浏览的运气不太好 或者也许我只是没有看到它 那么我该怎么做呢 例如 假设我有一个名为my string等于 hello
  • Discord.py 获取自定义状态

    如何通过discord py获取Discord用户自定义状态 我看过discord py 文档 我唯一能找到的是Member status https discordpy readthedocs io en latest api html
  • 为什么除法结果会根据强制转换类型而有所不同? (跟进)

    这是这个问题的后续 为什么除法结果会根据强制转换类型而有所不同 https stackoverflow com questions 25703304 why does a division result differ based on th