AM3354 浮点计算问题

小小小小小疯子 2018-01-15 11:41:14
小弟遇到一个问题,请大神指点一二:
软件硬件平台:WinCE6.0 + AM3354。
由于WinCE6.0编译器不支持浮点指令,小弟使用了ARM官方提供的VFP库。该库之前在WinCE6.0+S3C6410上使用,没有问题。
但是在当前的平台上,会出现如下问题:
机器在上电后,启动我们的数控软件,数控软件中有比较多的浮点运算。浮点运算的过程会出现偏差,比如:
正确的计算结果为:
540.63510936875002 :::0x4080E514B4388151
出现问题时结果为:
540.63510936874991 :::0x4080E514B4388150

正确的计算结果为:
2554.9807209000001:::0x40A3F5F6210CC002
错误的计算结果为:
2554.9807208999996:::0x40A3F5F6210CC001

计算数据都是类似的,就不一一举例了。通过数据比较,看出,其二进制浮点标示,最低位差了1。
正确结果比错误的差别就是最后一位的值。
小弟推测,可能是round规则的问题,但是找不到证据。请大神们指点一二。感激不尽。
S3C6410的硬件浮点处理单元为VFPv2,AM3354为VFPv3+NEON。

...全文
1367 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
感谢各位。找到问题了。 TI官方有一篇文档对该问题进行了说明。
  • 打赏
  • 举报
回复
引用 7 楼 curious_cat 的回复:
IEEE-754标准里面默认的rounding mode就是Round to nearest 你用的round to positive zero确实非常冷门啊。 Rounding mode The IEEE 754 standard requires all calculations to be performed as if to an infinite precision. For example, a multiply of two single-precision values must accurately calculate the significand to twice the number of bits of the significand. To represent this value in the destination precision, rounding of the significand is often required. The IEEE 754 standard specifies four rounding modes. In round-to-nearest mode, the result is rounded at the halfway point, with the tie case rounding up if it would clear the least significant bit of the significand, making it even. Round-towards-zero mode chops any bits to the right of the significand, always rounding down, and is used by the C, C++, and Java languages in integer conversions. Round-towards-plus-infinity mode and round-towards-minus-infinity mode are used in interval arithmetic http://infocenter.arm.com/help/topic/com.arm.doc.ddi0344b/DDI0344.pdf
这是ARM给的库的实现。没有浮点支持库的源码,仅仅是文档上的说明。
curious_cat 2018-01-17
  • 打赏
  • 举报
回复
IEEE-754标准里面默认的rounding mode就是Round to nearest 你用的round to positive zero确实非常冷门啊。 Rounding mode The IEEE 754 standard requires all calculations to be performed as if to an infinite precision. For example, a multiply of two single-precision values must accurately calculate the significand to twice the number of bits of the significand. To represent this value in the destination precision, rounding of the significand is often required. The IEEE 754 standard specifies four rounding modes. In round-to-nearest mode, the result is rounded at the halfway point, with the tie case rounding up if it would clear the least significant bit of the significand, making it even. Round-towards-zero mode chops any bits to the right of the significand, always rounding down, and is used by the C, C++, and Java languages in integer conversions. Round-towards-plus-infinity mode and round-towards-minus-infinity mode are used in interval arithmetic http://infocenter.arm.com/help/topic/com.arm.doc.ddi0344b/DDI0344.pdf
  • 打赏
  • 举报
回复
顶一下,各位大神看过来啊。
  • 打赏
  • 举报
回复
引用 3 楼 curious_cat 的回复:
把你用的库文件发出来,或者下载链接发出来看看就知道了。
http://download.csdn.net/detail/cpq37/7667239 使用的库链接如上,使用方法和下面的链接基本一致。 http://blog.csdn.net/cpq37/article/details/7425176 库没有源码。今天又看了库的支持文档,发现默认情况下,库是使用了round to positive zero模式。
curious_cat 2018-01-15
  • 打赏
  • 举报
回复
把你用的库文件发出来,或者下载链接发出来看看就知道了。
curious_cat 2018-01-15
  • 打赏
  • 举报
回复
ARM® Compiler ARM C and C++ Libraries and Floating-Point Support User Guide 3.2.5 Functions for handling rounding modes The fegetround() and fesetround functions let you get and set the current rounding mode. Note: The following functionality requires a floating-point model that supports exceptions. In ARM® Compiler 6 this is disabled by default, and can be enabled by the armclang command-line option -ffp-mode=full. C99 defines these functions as follows: int fegetround(void); int fesetround(int round); The fegetround() function returns the current rounding mode. The current rounding mode has a value equal to one of the C99 rounding mode macros or exceptions. The fesetround() function sets the current rounding mode to the value provided. fesetround() returns zero for success, or nonzero if its argument is not a valid rounding mode. 链接 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0098a/index.html
  • 打赏
  • 举报
回复
引用 1 楼 curious_cat 的回复:
参考WIKI里面的说明,应该是Rouding的问题,IEEE 754里面有5种Rounding modes,使用不同的选项就会有不同的结果; 不过这个误差对你应用的影响应该是非常小。 https://en.wikipedia.org/wiki/Floating-point_arithmetic#Rounding_modes 此外,WEC 7.0(WINCE 7.0), WEC 2013(WINCE 8.0)才支持硬件处理器(编译器选项里面可以设置使用使用硬件浮点运算)。 WINCE6.0的浮点运算是软件模拟的(即使处理器支持硬件浮点运算),相对而言,效率较低。
有个ARM官方的库,可以支持。我的理解,就是底层偷偷替换掉C运行库,fpcrt.dll。 我猜测是rounding的问题,根据我的分析,比较像。但是想要找到确切的证据。 误差的影响确实非常小。但是软件做的有问题,没有对acos的输入进行截断。 所以会出现acos(1.000000000000002)这种情况,导致软件崩溃。
curious_cat 2018-01-15
  • 打赏
  • 举报
回复
参考WIKI里面的说明,应该是Rouding的问题,IEEE 754里面有5种Rounding modes,使用不同的选项就会有不同的结果; 不过这个误差对你应用的影响应该是非常小。 https://en.wikipedia.org/wiki/Floating-point_arithmetic#Rounding_modes 此外,WEC 7.0(WINCE 7.0), WEC 2013(WINCE 8.0)才支持硬件处理器(编译器选项里面可以设置使用使用硬件浮点运算)。 WINCE6.0的浮点运算是软件模拟的(即使处理器支持硬件浮点运算),相对而言,效率较低。

19,502

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
  • 嵌入开发(WinCE)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧