use*_*395 5 javascript math bash qt qml
我想计算太阳围绕银河系的情况;the Math Formula is ((241828072282107.5071453596951 * 666) * 2) * 3.14159265359, using QML JavaScript I get the answer 1011954093357316100, when the correct answer is 1011954093357316200, a 100 miles off.
galaxyRadius="241828072282107.5071453596951";
currentTrackNumber=666; // Track Number like on a Record
pIe="3.14159265359"; // not the same as Math.PI
Run Code Online (Sandbox Code Playgroud)
我必须使用字符串,因为将这些大小的数字转换为浮点数会截断精度,我正在转换旧的 bash 脚本,并且它与 bc 一起工作得很好,而不是数学。
我已经尝试过这个:
orbitDist = ((( Number.parseFloat(galaxyRadius).toPrecision(20) * currentTrackNumber) * 2) * Number.parseFloat(pIe).toPrecision(12) );
Run Code Online (Sandbox Code Playgroud)
我得到的结果与以下相同:
orbitDist = ((( galaxyRadius * currentTrackNumber) * 2) * pIe );
Run Code Online (Sandbox Code Playgroud)
来自bash:
echo "$(bc <<< "scale=13;((241828072282107.5071453596951 * 666) * 2) * 3.14159265359")"
Run Code Online (Sandbox Code Playgroud)
Bash 是对的,而 JavaScript 错了近 100 英里,这太疯狂了,这让我吓坏了,JavaScript 浮点数学怎么会相差这么远,这只是一个例子,我有一整个应用程序充满了数字很近,但还不够近,相差 100 英里是不可接受的。
我不想处理指数,我想要作为整数的值,字符串很好,它作为字符串存储在数据库中,我只需要数学是正确的。
这是一个 QtQuick、QML、Felgo 应用程序,使用 Qml 和 JavaScript,因此需要在不同的平台上运行。我的下一个想法是 C++,或者适用于此类项目的数学库,JavaScript 或 C++ 的 QML 包装库会很棒,弄清楚如何使 JavaScript 在浮点上不那么糟糕会更好,我发现了一些 JavaScript Web 库,如果没有 Qml 下的大量工作,它们就无法工作,所以我只对有效的内容感兴趣,我做了很多研究,但没有找到我想要的东西。
因为 JavaScript 目前只支持整数(BigInt)的 bignum 。然后我在计算之前将其转换为 BigInt。并跟踪小数部分重新转换为浮点数。
const galaxyRadius="241828072282107.5071453596951";
const currentTrackNumber=666; // Track Number like on a Record
const pIe="3.14159265359"; // not the same as Math.PI
const orbitDist = ((( galaxyRadius * currentTrackNumber) * 2) * pIe );
console.log(orbitDist)
//// My approad
//Put all number into an array
var arrToMul = [galaxyRadius,currentTrackNumber, 2, pIe]
// Function multiple all item in array with BigInt format
function mulBigInt(arr) {
return arr.reduce(function (acc, e) {
return BigInt(e) * acc;
}, BigInt(1));
};
// Function get length of decimal part
function decLength(str) {
var dec = str.toString().split('.')[1];
return dec ? dec.length : 0;
};
// Function remove point in string to convert float to int
function rmPoint(strNum) {
return strNum.toString().replace('.', "");
};
// Main function
function cal(arr) {
// Get total decimal part length of all number
var pointSize = arr.reduce(function (acc, e) {
return acc + decLength(e);
}, 0);
// convert the all item to int (type string)
var newArr = arr.map(function (e) {
return rmPoint(e);
});
// Add point to reconvert BigInt to float(string actually)
var tmp = mulBigInt(newArr).toString().split('');
tmp.splice(tmp.length - pointSize, 0, '.');
// Return float result with string format
return tmp.join('');
};
const rs = cal(arrToMul)
console.log(rs, 'converted to BigInt:')Run Code Online (Sandbox Code Playgroud)