Open nycos62 opened 7 months ago
You can use fractions for that, like:"
math.fraction(1, 6).toString() // "0.1(6)"
math.fraction(1, 7).toString() // "0.(142857)"
EDIT: Fractions cannot work with BigNumber though, you'll have to calculate with fractions from the start.
thank you very much !! another stupid question... sorry... if I start from a string formula, which tools are available to get decimal period ? is there really only by fraction that I could achieve this ?
math.config({
number: 'Fraction'
})
math.simplify('cos(pi/n)'.replace(/n/g, 3),{},{exactFraction:true}).toString()
'cos(pi / 3)'
math.simplify('1/n'.replace(/n/g, 3),{},{exactFraction:true}).toString()
'1 / 3'
I wish I could from whatever str formula find the decimal period
@nycos62 , if you know limits on the denominator and numerator , you can use method from https://stackoverflow.com/questions/14002113/how-to-simplify-a-decimal-into-the-smallest-possible-fraction/14011299#14011299 to convert decimal to fraction, then use fraction to string as @josdejong says
p.s. perhaps, can you just work with fractions all the time?
You can use math.fraction(value).toString()
.
You should be aware though that the representation may not be exact, for example you may have a value like 0.3333333333
, then the question is is this the exact number, or is it a rounded representation of 1/3 and should it have an infinite number or digits? So, be careful with the precision you need to work with.
I might have found some sort of middle solution...
math.config({
number: 'BigNumber', // Default type of number:
// 'number' (default), 'BigNumber', or 'Fraction'
precision: 509 // Number of significant digits for BigNumbers
})
const a = math.bignumber("205.16666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667");
const b = math.bignumber("185.85714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714286");
const c = math.bignumber("19.129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258064516129032258065");
const d = math.bignumber("26.708333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333");
const e = math.bignumber("53.071428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571");
function findLongestSubstring (str) {
let candidate = "";
for (let i = 1; i <= str.length - i; i++) {
if (str.indexOf(str.substring(0, i), i) === i)
candidate = str.substring(0, i);
}
return candidate;
}
function rotateAndMoveLeft (str, substr, fromIndex) {
const rotate = (str) => `${str[str.length-1]}${str.slice(0, str.length-1)}`;
const lastIndex = substr.length - 1;
let rotatedStr = substr;
let pos;
// console.log(`str=${str}, substr=${substr}, fromIndex=${fromIndex}`);
for (pos = fromIndex - 1; pos >= 0; pos--) {
if (rotatedStr[lastIndex] === str[pos]) {
rotatedStr = rotate(rotatedStr);
} else {
pos++;
break;
}
}
const from = pos !== -1 ? pos : 0;
return {
subStr: rotatedStr,
from,
numMoved: fromIndex - from
};
}
function shrinkPattern (pattern) {
const _shrink = (head, tail) => {
if (tail.length === 0)
return head;
return tail.split(head).every(item => item.length === 0) ?
head : _shrink(`${head}${tail[0]}`, tail.slice(1));
}
return _shrink(pattern[0], pattern.slice(1));
}
function testRepeatingDigits (num) {
const str = num.toString().substring(0,num.toString().length-3);
const idx = str.indexOf('.');
if (idx < 0)
return false;
const digitStr = str.substring(idx + 1);
const [...digits] = digitStr;
// the first guess of repeating pattern from the right-most digit
const init = [...findLongestSubstring(digits.slice(0).reverse().join(''))].reverse().join('');
// no repeating patterns found
if (init.length === 0)
return {
result: (Math.round(num * 100) / 100).toString(),
pattern: "None"
};
// rotate the first guessed pattern to the left to find the beginning of the repeats
const searchFrom = digitStr.length - (init.length * 2);
const { subStr, from, numMoved } = searchFrom > 0 ?
rotateAndMoveLeft(digitStr, init, searchFrom) : { subStr: init, from: 0, numMoved: 0 };
// shrink the pattern to minimum
const pattern = shrinkPattern(subStr);
// truncate the digits overflows the two repeatings of the pattern
return {
result: `${str.substring(0, idx+1)}${digitStr.substring(0, from + pattern.length * 2)}...`,
pattern
};
}
function toStringVinculum(n) {
let test = testRepeatingDigits(n);
let overlineChar = '\u0305';//not compatible on android :/ , so usage of span
let nStr = n.toString();
if (test == false || test.pattern == 'None')
return n.toString();
else
{
return test.result.substring(0,test.result.length-(3+(2*test.pattern.length))) + '<span style="text-decoration:overline">' +test.pattern.split('').join('</span><span style="text-decoration:overline">') + '</span>';
}
}
console.log(toStringVinculum(a));
console.log(toStringVinculum(b));
console.log(toStringVinculum(c));
console.log(toStringVinculum(d));
console.log(toStringVinculum(e));
'205.1‾6'
'185.‾857142'
'19.‾129032258064516'
'26.708‾3'
'53.0‾714285'
Hello, maybe a stupid question, but is there a natural way to get periodicity in BigNumbers decimals
as you can see it ends with digit '7'
I wish to identify here a period of length 1 starting at decimal 2 : '0.1 ͞6'
thx