Javascript 使用NodeJS N-API计算浮点值时出现问题
各位好, 来自网络开发世界。我目前正在尝试编写一些C代码,将RGB值转换为XYZ值,NodeJS可以通过N-API使用该值。我遇到的问题是关于浮点计算的问题。以下是对我的问题的解释: 基于下面的C代码,此代码尝试将RGB值转换为XYZ值Javascript 使用NodeJS N-API计算浮点值时出现问题,javascript,c,node.js,node.js-addon,node.js-napi,Javascript,C,Node.js,Node.js Addon,Node.js Napi,各位好, 来自网络开发世界。我目前正在尝试编写一些C代码,将RGB值转换为XYZ值,NodeJS可以通过N-API使用该值。我遇到的问题是关于浮点计算的问题。以下是对我的问题的解释: 基于下面的C代码,此代码尝试将RGB值转换为XYZ值 char * colorType = getStringValue(env, funcParams[2], SPACELen); // m is either the value srgb | adobeRgb Matrix m = getEnumFromStr
char * colorType = getStringValue(env, funcParams[2], SPACELen);
// m is either the value srgb | adobeRgb
Matrix m = getEnumFromStr(colorType);
Rgb * rgb = getRGBFromJSObj(env, funcParams[0]);
xyz = generateXyzFromRgb(rgb, m);
我使用这个JS代码片段来调用我的库
const rgb = {
r: 255,
g: 255,
b: 255
};
const xyz = lib.getXyzFromRgb(rgb, "srgb", 10000);
expect(xyz).to.be.deep.equal({
x: 0.9504,
y: 1,
z: 1.0888
});
如果一切正常,输出应如下所示
{
x: 0.9504,
y: 1,
z: 1.0888
}
然而,我的输出是这个
{
x: 0.9502,
y: 0.9997,
z: 1.0886
}
正如你所看到的,输出是完全错误的然而,这种错误的输出只发生在我的本地计算机(OSX)上,并且只有在我试图使用JS代码段进行转换时才会发生。
事实上,当我试图通过Xcode直接使用下面的这段代码运行转换时,输出是正确的
// RGB and & m variable is outputing the same value as the conversion done by the C code above
xyz = generateXyzFromRgb(rgb, m);
此外,当我试图通过运行OSX的travis调用JS代码时,通过Docker在Ubuntu上调用JS代码时,JS代码也会输出正确的值
它是否与硬件或我编译库的方式或其他方面更相关
提前感谢您。在javascript v8引擎中。实际上只存在smi和double。 readFloatBE:当float传递到v8时,float将转换为double。 当你外出并四舍五入到一个浮动中时,它将提升到双精度 首先,如果您真的希望获得像C这样的值,则需要手动指定舍入的数字,并使用向上舍入的Number.prototype.toPrecision函数重新实例化Number对象: 供参考:
var v = 5.2
var buffer = new Buffer(5)
buffer.writeFloatBE(v)
var g = buffer.readFloatBE()
console.log(v)
console.log(g)
console.log(v==g)
console.log(Number(g.toPrecision(5)))
事实上,post by和JavaScript的数字是64位
当我对这个特性进行编码时,使用的数字类型是float(乍一看并没有考虑创建节点模块)。后来,我决定使用下面这样的小util方法将float转换为double
double v = *(double *) arg;
status = napi_create_double(env, v, &value);
奇怪的是在执行此转换时,我可能会随机丢失十进制精度,而它本不应该这样做(32位到64位),或者我可能遗漏了一些内容
稍后,我重构了相同的代码,但这次使用了double,它可以正常工作。非常感谢你们所有人
注意:当我在NodeJS绑定代码库中使用上述方法时,我惊讶地发现我之前没有出现十进制精度错误。C代码中的数字数据类型是什么?通常在任何编程语言中,数字都是二进制浮点值,执行严格的相等性测试是很棘手的。@Pointy数字数据类型是float。我应该把这个换成双倍的吗?。事实上,我看了IEE754,它看起来很棘手。。。然而,我发现奇怪的是,错误的输出只发生在我的机器上,而且只发生在使用JS代码段时,而不是在travis osx或Ubuntuthuth中的a上。C
float
type(通常)只有32位;JavaScript数字是64位的。@Pointy-Hmm是的,在使用浮点值之后,我将浮点值转换为双精度值,以便N-API使用该值。您是否认为在转换过程中可能会丢失精度?我想我应该马上把它转换成double,看看它到底是怎么回事。我可以返回一个缓冲区,而不是一个浮点值,这可能有助于提高精度