Lua can’t do math?

September 17, 2009

今天把项目中所有使用的脚本从python替换到lua,一切看起来很美,不过最后测试的时候发现一个非常诡异的问题,具体lua语句如下:

print("simple test: ")
print((10000 + 123456789) - 123456789)

程序打印出来的值竟然是10003,顿时被雷到了。虽然我知道lua用的是double作为基础的lua_number,但是人家已经很耐心的教育我们double是双精度类型,不会出现什么四舍五入的问题。于是打开linux上的终端运行lua进行同样的计算,这次得到的是正确的结果:10000。

想想也知道lua不会有这种低级的错误的,要不还不立刻被人骂死,于是开始找自己的问题,首先怀疑是我们的lua嵌入包裹代码的问题,仔细review了一遍代码,觉得不会影响到这么底层的问题。接着开始做实验,发现在服务器上的同样lua代码,运行的结果是正确的。经过无尽的折腾,最后发现了这么一个事实:

在directX的sdk文档里面,D3DCREATE这个条目里面有这么一条:

D3DCREATE_FPU_PRESERVE Set the precision for Direct3D floating-point calculations to the precision used by the calling thread. If you do not specify this flag, Direct3D defaults to single-precision round-to-nearest mode for two reasons:
- Double-precision mode will reduce Direct3D performance.
- Portions of Direct3D assume floating-point unit exceptions are masked; unmasking these exceptions may result in undefined behavior

D3D默认在创建设备的时候,会把双精度改成单精度,增加渲染的效率,所以lua也被殃及了,这也算是蝴蝶效应的一个体现吧。。。。。

恶心的问题只要原因找到了解决总是相对容易的,现在有两个方案:

  1. 将lua_number定义为int,缺点是lua内就不能使用小数
  2. 在D3D初始化的时候添加参数,让他不要改变计算精度,缺点是不知道对性能有多大影响

posted in Develop by Louis

Follow comments via the RSS Feed | Leave a comment | Trackback URL

1 Comment to "Lua can’t do math?"

  1. Davy.xu wrote:

    其实对于UI的话,完全可以定义成整形,呵呵。不过别人用UI做计算就郁闷了

Leave Your Comment

 
Powered by Wordpress and MySQL. Theme by Shlomi Noach, openark.org