Как вы делаете математику большого числа в QtQuick Qml, используя JavaScript - PullRequest
4 голосов
/ 27 марта 2019

Я хочу рассчитать обстоятельства Солнца вокруг Галактики; Математическая формула ((241828072282107.5071453596951 * 666) * 2) * 3.14159265359, используя QML JavaScript, я получаю ответ 1011954093357316100, когда правильный ответ 1011954093357316200, на расстоянии 100 миль.

galaxyRadius="241828072282107.5071453596951";

currentTrackNumber=666; // Track Number like on a Record

pIe="3.14159265359"; // not the same as Math.PI

Мне пришлось использовать строки, потому что преобразование этих чисел в числа с плавающей запятой урезает точность, я конвертирую старый скрипт bash, и он отлично работал с bc, а не с Math.

Я пробовал это:

orbitDist = ((( Number.parseFloat(galaxyRadius).toPrecision(20) * currentTrackNumber) * 2) * Number.parseFloat(pIe).toPrecision(12) );

Я получаю те же результаты, что и:

orbitDist = ((( galaxyRadius * currentTrackNumber) * 2) * pIe );

из bash:

echo "$(bc <<< "scale=13;((241828072282107.5071453596951 * 666) * 2) * 3.14159265359")"

Bash прав, а JavaScript не прав почти на 100 миль, это безумие, меня это бесит, как может быть JavaScript с плавающей запятой настолько далеко, и это только один пример, у меня полно приложений чисел, которые близки, но даже не достаточно близки, расстояние в 100 миль недопустимо.

Я не хочу иметь дело с показателями степени, я хочу получить значение как целое число, строки в порядке, оно хранится в базе данных в виде строки, мне просто нужно, чтобы Math был прав.

Это приложение QtQuick, QML, Felgo, использующее Qml и JavaScript, поэтому оно должно работать на разных платформах. Моя следующая мысль - C ++, или Math Library, которая работает для этого типа проекта, JavaScript или библиотека-обертка QML для C ++ была бы отличной, выяснить, как сделать JavaScript не таким плохим в Floating Point, было бы лучше, я нашел несколько JavaScript Библиотеки для Интернета, они не работают без большой работы под Qml, поэтому меня интересует только то, что работает, и я провел много исследований и не нашел то, что искал.

1 Ответ

0 голосов
/ 27 марта 2019

Из-за JavaScript на данный момент только поддержка bignum только для целых чисел (BigInt).Затем я конвертирую его в 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 acctually)
  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:')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...