- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
有一段代码把我搞糊涂了,是在windows下运行的!这是代码:
#define point_float2uint(x) *((unsigned int *)&x)
float divide_1000(float y)
{
float v = y / 1000.0f;
return v;
}
float divide_1000(int y)
{
float v = float(y) / 1000.0f;
return v;
}
void float_test(void)
{
int num[5] = {67975500, 67251500, 67540620, 69435500, 70171500};
for (int i = 0; i < 5; ++i)
{
int a = num[i];
float af_f = divide_1000(float(a));
float af_i = divide_1000((a));
printf("src num:%d, af_f:%f, %x, af_i:%f, %x\n", num[i], af_f, point_float2uint(af_f), af_i, point_float2uint(af_i));
}
}
这是由 vs2005 编译的输出:
src num:67975500, af_f:67975.507813, 4784c3c1, af_i:67975.500000, 4784c3c0
src num:67251500, af_f:67251.507813, 478359c1, af_i:67251.500000, 478359c0
src num:67540620, af_f:67540.625000, 4783ea50, af_i:67540.617188, 4783ea4f
src num:69435500, af_f:69435.507813, 47879dc1, af_i:69435.500000, 47879dc0
src num:70171500, af_f:70171.507813, 47890dc1, af_i:70171.500000, 47890dc0
问题是:为什么我使用“divide_1000”,在windows中得到不同的结果?这不是我想要的!而且我发现并不是所有的整数结果都不同,但有些就像上面的代码一样。
这是输出,由 debian 中的 gcc4.4.5 编译:
src num:67975500, af_f:67975.507812, 4784c3c1, af_i:67975.507812, 4784c3c1
src num:67251500, af_f:67251.507812, 478359c1, af_i:67251.507812, 478359c1
src num:67540620, af_f:67540.625000, 4783ea50, af_i:67540.625000, 4783ea50
src num:69435500, af_f:69435.507812, 47879dc1, af_i:69435.507812, 47879dc1
src num:70171500, af_f:70171.507812, 47890dc1, af_i:70171.507812, 47890dc1
我在使用不同的函数“divide_1000”时得到了相同的结果。这就是我想要的。
最佳答案
这里涉及很多影响结果的代码生成设置。当使用“经典”FPU 指令进行浮点计算时,在默认浮点模型(即“精确”模型)下的非优化代码中可以观察到您报告的差异。
编译器按字面意思翻译第一次调用:原始整数值首先转换为 float
- 4 字节浮点值 - 存储在内存中(作为函数参数)。此转换将值四舍五入为 +6.7975504e+7
,这已经不精确了。随后,float
值从第一个函数内的内存中读取,并用于进一步的计算。
第二次调用传递一个int
值给函数,该值直接加载到高精度FPU寄存器中,用于进一步的计算。即使您在第二个函数中指定了从 int
到 float
的显式转换,编译器还是决定忽略您的请求。此值永远不会按字面意思转换为 float
,这意味着上述精度损失永远不会发生。
这就是造成您观察到的差异的原因。
如果您将第二个函数重写为
float divide_1000(int y)
{
float fy = y;
float v = fy / 1000.0f;
return v;
}
即添加一个将 float
值保存到内存中指定位置的附加步骤,编译器将在未优化的代码中执行该步骤。这将导致结果变得相同。
同样,上述内容适用于未经优化编译的代码,此时编译器通常会尝试非常接近地(但并不总是准确地)翻译所有语句。在优化代码中,编译器消除了到 float
的“不必要”中间转换以及两种情况下所有“不必要”的中间内存存储,从而产生相同的结果。
您可能还想尝试其他浮点模型(即“严格”和“快速”)以了解它如何影响结果。这些浮点模型专门用于处理您观察到的问题。
如果您更改编译器的代码生成设置并使其使用 SSE 指令进行浮点运算,结果也可能会改变(在我的实验中,当使用 SSE2 指令集而不是 FPU 指令时,差异消失)。
关于c++ - 奇怪的,float类型的参数在windows中传入函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17441731/
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: How do I copy an object in Java? 我的类中有一个函数 Claus它调用一个函数来接受
任何人都可以给我一个 linux 内核驱动程序手册或示例的链接,它可以修改来自/到指定 ip 端口的传入/传出数据包吗? 谢谢! 最佳答案 Kprobes 是一种可以做到这一点的方法。这是一个使用具有
我有一个 3rd 方网站,该网站具有发送到特定 url 的 webhook。我将其设置为发送到我网站上的空白页面(例如:www.mysite.com/webhook.php) 我在 webhook.p
我对传递的约定感到困惑*args在 super().__init__()在python继承中。 我了解需要使用关键字参数 **kwargs因此,如果需要,CRO 中的类可以采用所需的参数,但为什么还有
我有一个 webapi (.NET core 3.1) 方法,它正在获取 XML 并反序列化为对象。但是一些标签的开头和结尾是不一样的。例如,如果以 打开然后它以 关闭.因此 XML 格式不正确。
是否有一个 hg 命令可以组合 hg传入 + hg传出 + hg status? 这会告诉您是否有任何远程内容需要传入,是否有任何本地提交的内容需要出去,或者是否有任何本地更改需要提交。 最佳答案 虽
据我了解,你无法在两部 iPhone 之间建立连接(如果我错了,请纠正我)。因此,我想做的是在客户端应用程序之间放置一台服务器,该服务器接受消息并将其重新分发给适当的人员。本质上,该应用程序将允许人们
我正在使用 Apache Camel 向我的 Java 服务发送消息。我在消费者路线上保留了 transacted=true。我还需要发送有关成功处理 JMS 消息的电子邮件。 我正在使用以下代码来注
这个问题在这里已经有了答案: What does "this" point to? (5 个答案) 关闭 4 年前。 public class CommandForm extends Form im
我是一名 Swift 开发人员,也是 Dart 的新手。我正在尝试编写一些通用方法。 我想知道我是否可以在 Dart 中实现类似的事情。 //Swift version public func mod
基本上有人问我是否有任何方法可以捕获和下载通过邮件服务器的所有传入和传出电子邮件(最好是文本格式)。这种下载方法需要使用PHP或类似的服务器端语言来完成。 如果我能通过上述阶段,那么最终目标就很容易实
我正在学习 Flask 并且有一个关于动态路由的问题:是否可以传入一个可接受的路由列表?我注意到 any 转换器有潜力,但很难找到它的使用示例。基本上我有不同的端点组,它们应该在它们之间触发相同的 A
我正在学习如何使用 pthread 函数。在这里我想使用 pthread_create 创建一个线程并用它计算一些数字的平均值。(数字序列末尾的0表示已经完成) 这是我到目前为止写的: #includ
我需要传递一个带有字段“nombre”作为参数的条件 目前我这样做: @xcondicion= {:nombre.like => "%#{params[:qyBusqueda]}%"} cliente
我有以下两个 parseInt(),我不太清楚为什么它们会给我不同的结果: alert(parseInt(0.00001)) 显示 0; alert(parseInt(0.00000001)) 显示
我有一个使用 SODA 包来操作 JSON 数据库的 PL/SQL 处理程序。我想: 读取有效负载中键 id 的值 将负载 JSON 写入数据库中的新文档。 要执行第 1 步,处理程序将 :body
我正在使用 Oracle 试用 Dapper,我试图运行多结果集查询,但 Oracle 需要 dbtype 的 refcursor。 StringBuilder query = new StringB
我在将“工作表”选项卡重命名为任何文件名时遇到问题。这样做的问题是,如果用户意外下载工作表两次,Windows 会将 template(1).csv 附加到文件中,以保持其下载目录中的唯一性。在 Ex
我将 id 作为字符串传递到函数中。我想使用该 ID 来更改背景颜色。我用过: $("#"+address).css("background-color", "#3399FF"); 但它没有改变背景颜
我有一个 ListSourceAdapter.java 类, class ListSourceViewHolder extends RecyclerView.ViewHolder implements
我是一名优秀的程序员,十分优秀!