I've tried two versions of a karatsuba multiplcation algorithm and they both fail with different results when I test them with large X and Y values.
The parameters I'm using
const x = 3141592653589793238462643383279502884197169399375105820974944592
const y = 2718281828459045235360287471352662497757247093699959574966967627
const solution = 8539734222673567065463550869546574495034888535765114961879601127067743044893204848617875072216249073013374895871952806582723184
Algorithm1 I got from this page: https://gist.github.com/haocong/c2d9b2169d28eb15a94d
Expected value to equal:
8.539734222673567e+126
Received:
7.292575034127423e+22
Algorithm2 I got from this page: https://stackoverflow.com/a/28376023/604950
Expected value to equal:
8.539734222673567e+126
Received:
6.0002556749374185e+22
To reproduce you can grab this PR:
https://github.com/Falieson/Algorithms-Illuminated-Part1_TheBasics/pull/1
That is because you are using numbers that are too big and JavaScript doesn't know how to handle them.
The Number.isSafeInteger() method determines whether the provided value is a number that is a safe integer.
2^53 - 1 is a safe integer: it can be exactly represented, and no other integer rounds to it under any IEEE-754 rounding mode. In contrast, 2^53 is not a safe integer.
console.log(warn(Math.pow(2, 53)));
// expected output: "Precision may be lost!"
MDN
e.g. in your second algorithm you are doing
var res = (z2 * Math.pow(10, 2 * m ) ) + ( (z1-z2-z0) * Math.pow(10, m )) + z0;
which is not a safe operation in your case and JavaScript fails to compute it properly, giving you a wrong result.
If you put this code under the above mentioned line, you will see that.
console.log(Number.isSafeInteger(10 ** (2 * m)));
This evaluates to false.
Related
I have a javascript program that looks like this:
function dosine(){
var num = new Decimal(document.getElementById('num').value);
if(document.getElementById('degrad').value == "degrees"){
num = (num*Math.PI)/180;
console.log(num);
}
num = Decimal.sin(num);
console.log(num.toString());
numinverse = Decimal.asin(num);
if(document.getElementById('degrad').value == "degrees"){
num = num * (180/Math.PI);
numinverse = numinverse * (180/Math.PI);
}
document.getElementById('resultsine').innerHTML = "Sine: " + num.toString();
document.getElementById('resultinverse').innerHTML = "Inverse Sine: " + numinverse.toString();
}
In my program, I am now using Degrees.sin and Degrees.asin because of floating-point weirdness with the Math library, but when I get the sin output for 64 I get 51.49710550442818, but on my physical calculator I get 0.920026038197 0.8987940463. Am I using this library wrong, or is my code just not good? I am pretty new to javascript so advice would be very much appreciated. Thanks!
This has nothing to do with Decimal. You convert num to radians, then you take a sine of it. Finally you convert the result of the sine (which should be a proportion from 0 to 1, not an angle!) from radians to degrees, which makes no sense - it's like converting weight from feet into metres.
This could be avoided by using better naming conventions, using variable names that make sure you know what the variable contains. num is not very semantic - all it tells you is that it has a number in it. Consider angle_in_degrees, angle_in_radians and sine. Then it would be immediately obvious that this is not what you want:
angle_in_radians = Decimal.sin(angle_in_radians) // result is a sine ratio, not an angle!
angle_in_degrees = angle_in_radians * (180 / Math.PI); // good operation on bad data
Another big point is that your code does not stay in Decimal. JavaScript cannot override the default operations, so you have to use Decimal methods to calculate, not +, * and /. Note this:
Decimal(1) + 3 // incorrect
// => "13"
Decimal(1).add(3).toNumber() // correct
// => 4
Finally, unless you are dealing with financial systems, the floating point error is usually negligible; moreover, the result of sine function is irrational, so it can't be represented in Decimal any more correctly than in floating point anyway. Unless you have a use case that makes Decimal.js necessary, just use the normal numbers.
I was just curious, whether a number in JavaScript can ever reach Infinity.
The range of JavaScript numbers is pretty good enough -- 2 to the power of 64 different numbers, which is about 18 Quintilian (an 18 with 18 zeros after it). That’s a lot.
Now, I've few questions here:
What would really happen when a number grows beyond that range? Would JavaScript refer it as a new Infinity number?
What are all the scenarios in JavaScript, where the value Infinity could be assigned to a variable in runtime?
Let's look at a code example,
Attempting to write a method incrementNumToInfinity() to increment value of a certain number of times, so that a === b can evaluate to be true (also, to look at other possible scenarios, where the JavaScript Engine could assign the value Infinity to a variable in runtime).
var a = 1000; // a positive number
var b = Infinity;
console.log(a === b); // It returns false, that's expected
function incrementNumToInfinity(num) {
// Logic to convert our variable num into Infinity
return num;
};
a = incrementNumToInfinity(a); // Input: 1000, Expected output: Infinity
console.log(a === b); // Should return true
Can a number in JavaScript ever reach to Infinity in runtime?
It is possible at run time to get a number which is the result of a computation and which has for value Infinity. Nina Scholz has shown one such case: if you do x = 1 / 0, x will have for value Infinity.
What would really happen when a number grows beyond that range [i.e beyond the range JavaScript can handle]? Would JavaScript refer it as a new Infinity number?
We can try it. Number.MAX_VALUE is the maximum floating point number that JavaScript can represent. If you run this:
Number.MAX_VALUE + 1
You get a big number but not Infinity. What's going on there? Hmm, on a hunch let's try this:
Number.MAX_VALUE + 1 === Number.MAX_VALUE
The result is true. Say yhat? The problem is that floating point numbers have a limited precision, when I add 1 to Number.MAX_VALUE there isn't enough precision to register the increment.
If you try this:
Number.MAX_VALUE * 2
Then you get Infinity.
What are all the scenarios in JavaScript, where the value Infinity could be assigned to a variable in runtime?
"all the scenarios"... hmm... There are multiple issues with producing an enumeration of all the scenarios. For one thing, it is not clear what criteria should distinguish one scenario from one another. Is -Math.log(0) a different scenario from 1 / 0. If so, why? Then there's the issue that JavaScript engines have quite a bit of leeway to implement math functions. For instance, Math.tan is specified like this in the current draft:
Math.tan(x)
Returns an implementation-dependent approximation to the tangent of x. The argument is expressed in radians.
If x is NaN, the result is NaN.
If x is +0, the result is +0.
If x is -0, the result is -0.
If x is +∞ or -∞, the result is NaN.
It does not mandate a value for Math.tan(Math.PI / 2) If you recall your trigonometry classes, pi / 2 is 90 degrees and at that angle the tangent is infinite. Various versions of v8 have returned Infinity or a very large positive number. (See this question.) The specification does not mandate one result over the other: implementations are free to choose.
So practically if you start with a set of cases that you know mathematically should produce Infinity, you don't know whether they will actually produce that until you try them.
The part of your question with the incrementNumToInfinity function is not completely clear to me. You seem to be asking whether you can reach infinity simply by incrementing a number. It depends on what you mean. If you mean this:
let x = 0;
while (x !== Infinity) {
x++;
}
This will never terminate. x won't ever reach beyond Number.MAX_SAFE_INTEGER + 1. So it won't reach Infinity. Try this:
let x = Number.MAX_SAFE_INTEGER + 1;
x === x + 1;
You'll get the result true. That's again running into precision problems. The increment of 1 is not big enough to make a difference within the precision available to you.
Changing the increment to 2, 5, 10 or 10000000 does not really fix the issue, it just changes how far you can go before your increment no longer makes any difference.
Can a number in JavaScript ever reach to Infinity in runtime?
Assume your program does not have memory leak. I believe it can reach Infinity.
console.log(Number.MAX_SAFE_INTEGER)
// 9007199254740991
console.log(Number.MAX_VALUE)
// 1.7976931348623157e+308
var i = Number.MAX_SAFE_INTEGER
while (i != Infinity) {
i += Math.pow(10, 307)
console.log(i)
}
// 1.0000000000000005e+307
// 2.000000000000001e+307
// 3.0000000000000013e+307
// 4.000000000000002e+307
// 5.000000000000002e+307
// 6.000000000000003e+307
// 7.000000000000003e+307
// 8.000000000000004e+307
// 9.000000000000004e+307
// 1.0000000000000004e+308
// 1.1000000000000004e+308
// 1.2000000000000003e+308
// 1.3000000000000003e+308
// 1.4000000000000003e+308
// 1.5000000000000002e+308
// 1.6000000000000002e+308
// 1.7000000000000001e+308
// Infinity
The ratio of the square root of a square multiplied by PI of the same square subtracting PI to account for infinite decay as it approaches infinity, equals infinity. Or proving Archimedes wrong and right at the same time. PI and square are equivalent because neither will ever reach 0. This phenomenon also explains the zero boundary in the Pythagorean theory where A squared + B squared = c squared while approaching infinity.
Math.sqrt(1) / (Math.PI * ((Math.sqrt(1))) - Math.PI)
This is in result to the Fox and Duck Riddle. As the duck moves 1r of the distance to the pond the fox moves 180deg or the sum equivalent of the squares of its opposing and adjacent angles, we are give the square 2^2 (the travel distance from the center of the pond) Square root PI to the given 1:4 ratio therefor the hypotonuse of the triangle over pi - pi = Infinity or a 1:1 relationship with opposing vectors at any specific point.
ad 2:
What are all the scenarios in JavaScript, where the value Infinity could be assigned to a variable in runtime?
You could take a division with zero.
var x = 1 / 0;
console.log(x);
I am using various JavaScript Math functions and, due to floating point numbers, these functions occasionally return values that are either 0.000000001 larger or smaller than the correct integer answer. I am looking to set up an if-else statement for said functions that will return the correct integer answer should the value be within some small range of an integer (note that the non-specificity of said integer is of utmost importance).
So I am asking, is there a way, using JavaScript, to determine if the value returned from a math function (Math.cbrt() for example) is within some margin of a non-specific integer?
NOTE: I have tried using Number.EPSILON in a function which calculates the x-th root of a number like so
var index = $('#Index').val();
var radicand = $('#Radicand').val();
var powerXroot = Math.pow(radicand,(1/index))+(Number.EPSILON * Math.pow(radicand,(1/index)));
but it doesn't work for all indicies.
You can use Math.round() to get the nearest integer to the result. If this integer is within 0.000000001 of the result, replace the result with the integer instead.
Say, you have computed var x = ... and want to make it an integer if it's sufficiently close to one.
function roundIfAlmostInteger(x) {
if (Math.abs(x - Math.round(x)) < 0.000000001) {
x = Math.round(x);
}
return x;
}
Illustration:
x = 2.3 - 0.1 - 0.2; // now x is 1.9999999999999998
x = roundIfAlmostInteger(x); // now x is 2
I get two different results when attempting to calculate and round these numbers. The today number is 336887 and the yesterday number is 336582. I had a similar issue with another field, but after updating the Java code the discrepancy disappeared.
Javascript Code:
document.getElementById("txt1").value = ((today - yesterday) / 10000).toFixed(3);
Android Code:
public Double RoundDouble(Double num, Integer places)
{
Double temp = Math.pow(10.0, places);
num = num * temp;
Math.round(num);
num = num / temp;
return num;
}
Double total = RoundDouble((today - yesterday) / 10000,3);
txt1.setText(df.format(total ));
The Javascript code returns .031 while the Android code returns .030. I did the Math and before rounding, the number is .0305. I'm unsure what is causing this issue as the other field I had the issue with rounds .0295 to .030 properly.
The fraction ((336887 - 336582) / 10000) is not representable as an IEEE-754 double precision number. If you try ((336887 - 336582) / 10000).toFixed(20) you'll get 0.03049999999999999933.
The reason for the difference in the Android version could be the way you handle the return of Math.round(num): you ignore it. You might find it more useful to change the line to num = Math.round(num);.
It is also possible to change the rounding mode in Android. The default rounding mode in ECMAScript is nearest-to-even which is HALF_EVEN in Android.
I failed to find any constant in JS language which represents MAX UINT 32
Does it exists? I can have hardcoded the number itself, but i prefer to go in the more appropriate path of coding
For integers, Number.MAX_SAFE_INTEGER would be appropriate, as it's the maximum safe integer in JavaScript (2^53 – 1). The 53 power comes from how the double-precision floating-point numbers work. Those are also used in JavaScript to store numbers.
// In the safe integers zone:
const a = Number.MAX_SAFE_INTEGER - 1;
const b = Number.MAX_SAFE_INTEGER - 0;
console.log(a); // 9007199254740990
console.log(b); // 9007199254740991 (b + 1)
console.log(a === b); // false
// Outside the safe integers zone:
const x = Number.MAX_SAFE_INTEGER + 1;
const y = Number.MAX_SAFE_INTEGER + 2;
console.log(x); // 9007199254740992
console.log(y); // Also 9007199254740992, because precision....
console.log(x === y); // true
By the way, imagine that would happen if your iteration meets this kind of unsafe zone - infinite loop.
See also:
Number.EPSILON for the difference between 1 and the smallest floating point number greater than 1;
Number.MAX_VALUE for maximal number representable in JavaScript - not integer, but floating point.
Number.MIN_SAFE_INTEGER - for minimal safe integer (negative) in JavaScript.
Number.MIN_VALUE - for minimal negative number overall (floating point).
In some cases it's nicer to just use use Number.POSITIVE_INFINITY (or Number.NEGATIVE_INFINITY for negative), like when finding max/min values - for empty set you would get this not quite valid numerical value, that you can more easily notice and understand.
On linked pages you can also find other interesting stuff, like Number.isSafeInteger function to check whenever number is safe integer.
It does not exist, however you can have Max Numeric Value returned by Number object
You can see it here
alert(Number.MAX_VALUE);
Reference
javascript was no ints every number is a floating point number which is of class Number. The max value of that is Number.MAX_VALUE but that is almost certainly not what you are looking for (Number.MAX_VALUE = 1.7976931348623157e+308)
Try This:
<script>
function myFunction()
{
document.getElementById("demo").innerHTML=Number.MAX_VALUE;
}
</script>
Description
The MAX_VALUE property has a value of approximately 1.79E+308. Values larger than MAX_VALUE are represented as "Infinity".
Because MAX_VALUE is a static property of Number, you always use it as Number.MAX_VALUE, rather than as a property of a Number object you created.
Example: Using MAX_VALUE
The following code multiplies two numeric values. If the result is less than or equal to MAX_VALUE, the func1 function is called; otherwise, the func2 function is called.
if (num1 * num2 <= Number.MAX_VALUE) {
func1();
} else {
func2();
}