How to change the length of the number after floating point - javascript

So, I have an object.
var position = {
x: 1,
y: 0
}
After few operations x or y can become something like 0.3700000000000001. However, I need it to be 0.37. I tried:
position[x].toFixed(2)
What is the right way to get get rid of 00000000000001 ?

position[x] will get property of the position object which will be equal to value variable x. You should use position.x.
And you also need to change the value of position.x because position.x.toFixed(2) will not change the value.
position.x = position.x.toFixed(2)
toFixed() returns a string. You should convert it to float again using +.
console.log(+(0.3700000000000001). toFixed(2))

There should not be any problem except using the string key or dot notation:
var position = {
x: 0.3700000000000001,
y: 0
}
position.x = +position.x.toFixed(2); // + converts the resulted string to number
console.log(position.x);

If you want a number, there is no way to drop 00000000000001 to get 0.37 exactly. Like for other languages (most hardware supports IEEE 754), the number 0.37 does not exists. If scanning 0.37 it is rounded to the nearest possible number: 0.37.toPrecision(18) shows "0.369999999999999996".
Because of this, toFixed() returns a string and not a number. So it is nonsense to use toFixed() and convert the result back to a float.
The easiest solution is to live with these unexact values and use toFixed() for output only (that is the idea of toFixed()).
Another solution for e.g. money is, to store all values as cent/penny and divide the values by 100 only on output: ($cent/100).toFixed(2)

You are getting the value but you are not storing it, so the original vulea is not changed. You need to do:
var position = {
x: 1,
y: 0
}
position.x=position.x.toFixed(2)

Related

Determine if a numerical value is within some margin of a non-specific integer

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

Getting input to round to integer value if result decimal is followed by a series of 9s

I have a JavaScript calculator which uses the Math.cbrt() function. When I calculate the cube root of 125 it returns 4.999999999999999. I understand that I could use Math.round() to round any answers that this function returns to integer values, but I do not want to do that exactly. Is there a way to use this if and only if the result of calculation is some number followed by a string of 9s (or something similar like 4.99999998 perhaps) after the decimal?
What you are dealing with is the frustration of floating point numbers in computing. See the Floating Point Guide for more information on this critical topic.
The short version:
Certain non-integer values cannot be represented accurately by computers, so they store a value that is "near enough". Just try evaluating 3.3 / 3 in your favourite REPL.
Say what?!
Computers are supposed to be perfect at this numbers/math thing, right? Can I trust any answer they give me?
Yes, for integers, they are pretty much perfect. But for non-integer calculations, you should assume that answers won't be exact, and account for these floating point errors.
The solution in Javascript
In newer versions of Javascript, you have a defined constant Number.EPSILON, which is the smallest difference between the actual number and the approximation that it can actually store.
Using this, you can multiply that constant by the result you get and add it to the result and you should get the exact value you require.
function cbrt(n) {
return Math.cbrt(n) + (Number.EPSILON * Math.cbrt(n));
}
Alternatively, you can use the rounding behaviour of the .toFixed() method on numbers together with the parseFloat() function if you only care about numbers up to a certain number of decimal places (less than 20).
function num(n, prec) {
if (prec === void 0) prec = 8; // default to 8 decimal places
return parseFloat(n.toFixed(prec));
}
var threshold = 0.999; // set to whatever you want
var fraction = result % 1;
if (fraction >= threshold) {
result = Math.round(result);
}

How to prevent a number from using number1"E"number2

I need help because if I try to write a number that has a whole bunch of zeroes, it will come out as num1Enum2.
ie: for a googol it would write "1E100".
I want it to actually write the number, rather than the shortened form. How would I do this?
Note: I want it to still be an integer rather than a string.
If you "write out" a number, you get a string. Period. "Writing out" means outputting a sequence of characters that represent the number. But that's what a string is: a sequence of characters.
A number like 1E100 is too big to represent as a normal-sized integer, even internally. To get a value that big as an integer, you'll have to use some sort of library to represent big integers. Search around for one. There are several, with names like "BigInt", "BigInteger", "BigNumber", "LongDecimal" and so on. They should all be able to store internally arbitrarily large integer values, and should all provide a way to turn that value into a string, which you can then write out. Pick one you like.
You could try a big number handling library, like big.js. Otherwise, your only solution will be to split your big numbers into arrays and write your own math functions to manipulate them -- something like this function to treat an array as an integer and increment it:
var longVal=[0];
// inherits global array longVal[]
// increments each element from right to left
function inc() {
for (var i=longVal.length - 1; i>=0; i--) {
if (++longVal[i] == 10) {
longVal[i] = 0;
if (!i) {
longVal.splice(0, 0, 0);
i++;
}
continue;
}
else break;
}
}
I think if you exceed the length limit of your array, you could probably change the if (++longVal[i] == 10) line to something like if (++longval[i] == 1000000000) for great justice, but you'd have to left pad each array element except the first with zeros to make it ten digits. I haven't tested that though. My answer is the concept, rather than the implementation.

JavaScript: represent float as product of integer and power of ten

For instance, I have float 1.1111111111 and need to get 11111111111 and 10.
I want to avoid functions, which may change part after point as I need it to show metric prefixes.
It may look simple with strings, I am just not sure if it is a proper way in JavaScript.
The modular division operator '%' can be used to get the remainder of a division in JS. This means that if we perform the modular division of a floating point number by 1, we get the value after the decimal point. Further, if we build a loop where we multiply by 10 until there is no longer anything after the decimal point, we can find the smallest power of ten we can multiply the original number by to get an integer.
Example below:
function getE(floatingPointValue)
{
var x = floatingPointValue;
var digitsAfterDecimal = 0;
while(x % 1 != 0)
{
x = x * 10;
digitsAfterDecimal++;
}
return x.toString() + " *10^-" + digitsAfterDecimal;
}
Fiddle: http://jsfiddle.net/L8XtP/2/
Hope this helps!

Function returning NaN when I try to generate basic math operations

I am trying to generate randomly basic math operations(addition, subtractions, multiplication and division) and sometime my function returns NaN.
I used function parseInt(), but I still have the same problem. I will appreciate if anybody can help me with any suggestion.
Thank you in advance!
Here is my code:
function randNum(min,max)
{
var num = min+Math.floor((Math.random()*(max-min+1)));
return num;
}
var choose, operator, firstNum, secondNum,rightAnswer;
function getProb()
{
var chooseOp=randNum(1,4);
choose=parseInt(chooseOp);
if (choose==1)
{
oprator="+";
var choose1=randNum(0,10);
var choose2=randNum(0,10);
firstNum=parseInt(choose1);
secondNum=parseInt(choose2);
document.getElementById("mathProb").innerHTML=firstNum+operator+secondNum+"=";
rightAnswer=choose1 + choose2;
}
else if (choose==2)
{
operator="-";
var choose1=randNum(0,10);
var choose2=randNum(0,10);
firstNum=parseInt(choose1);
secondNum=parseInt(choose2);
document.getElementById("mathProb").innerHTML=firstNum+operator+secondNum+"=";
rightAnswer=firstNum - secondNum;
}
else if (choose==3)
{
operator="x";
var choose1=randNum(0,10);
var choose2=randNum(0,10);
firstNum=parseInt(choose1);
secondNum=parseInt(choose2);
document.getElementById("mathProb").innerHTML=firstNum+operator+secondNum+"=";
rightAnswer=choose1 * choose2;
}
else if (choose==4)
{
operator="/";
var choose1=randNum(0,10);
var choose2=randNum(0,10);
firstNum=parseInt(choose1);
secondNum=parseInt(choose2);
document.getElementById("mathProb").innerHTML=firstNum+operator+secondNum+"=";
rightAnswer=choose1/choose2;
}
}
When choose==1, operator is misspelled as oprator. If you correct it, problem is solved
http://jsfiddle.net/uERwd/2/
UPDATE:
Your code can be made shorter as: http://jsfiddle.net/uERwd/3/
Your division operation has the possibility of dividing by zero, which would return NaN.
Your "NaN" bug is here :
rightAnswer=choose1/choose2;
choose1 an choose2 are integer in [0, 1].
One time over 121, you're dividing 0 by 0, wich gives NaN.
And a little less than one time over 11, you're dividing a not null number by 0, wich gives Infinity.
You need to specify with a number that represent numeral system, tipically, base 10
http://www.w3schools.com/jsref/jsref_parseint.asp
Add the number 10 to the function call like this
firstNum = parseInt(choose1, 10);
When you randomly choose the division operator, it's possible to have zero come out for both choose1 and choose1, which means you attempt to evaluate rightAnswer = 0 / 0;. In Javascript, this equals NaN. Additionally, and this should happen more often, if you choose zero in the denominator any other number in the numerator the answer will come out as Infinity. Of course, zero over anything is zero.
It's a simple syntax error:
oprator="+"; // should be `operator`
That's why this statement...
firstNum+operator+secondNum+"=";
... will actually be evaluated as ...
firstNum+undefined+secondNum+"=";
The first pair will give you NaN, NaN + Number will be a NaN again, and NaN + String ("=") will result in NaN converted to string, then appended with '=' (hence resulting 'NaN=').
I'd strongly recommend placing "use strict"; line at the beginning of your scripts to catch such errors. With this, you'll get an error:
ReferenceError: assignment to undeclared variable oprator
... and won't need to make SO parse your script for errors instead. )
Sidenotes, I have plenty of them:
your randNum function will return you a Number, so no need to use parseInt (you may have to convert arguments of this function, but even that seems not to be necessary here) on its result;
if you divide by zero, you get Infinity; if you divide zero by zero, you get NaN as a result; be prepared or adjust the minimums. )
you violate DRY principle, repeating most of the statements outputting a result, why don't convert them into a function? Check this snippet (started by #sv_in, completed by me) for example how to do it.

Categories