I have custom calculator with js, everything was normal until i found 1.2101997764095421e-12 sometimes X.XXe-13, X.XXe-14
What is this ? How to convert it ?
Update :
I have knowledge in excel for this calculator, the result for 1.2101997764095421e-12 should be a 14,78
Those are really long floating point number, and the e-12 represents that there are 12 decimals. To convert it to your desired format you can do this:
var converted = Math.round(number * 100) / 100
This is nothing specific to javascript but a common mathematical notation meaning the following:
1e-1 = 0.1
1e-2 = 0.01
x.xxe-13 points to a number having 13 decimals after 0.
This is a representation of Scientific Notation. You can translate the eN to mean x10^N. When a Float number gets to large or small the string representation number will look that way.
1.12345e5 = 1.12345x10^5 = 112345
1.12345e-5 = 1.12345x10^-5 = .0000112345
Related
I tried to convert number to string in JavaScripts using toString() but it truncates insignificant zeros from numbers. For examples;
var n1 = 250.00
var n2 = 599.0
var n3 = 056.0
n1.toString() // yields 250
n2.toString() // yields 599
n3.toString() // yields 56
but I dont want to truncate these insignificant zeros ( "250.00"). Could you please provide any suggestions?. Thank you for help.
The number doesn't know how many trailing 0 there are because they are not stored. In math, 250, 250.00 or 250.0000000000000 are all the same number and are all represented the same way in memory.
So in short, there is no way to do what you want. What you can do is format all numbers in a specific way. See Formatting a number with exactly two decimals in JavaScript.
As far as I know, you can't store number with floating zeros, but you can create zeroes with floating zeroes, by using toFixed:
var n1 = 250;
var floatedN1 = n1.toFixed(2); //type 'string' value '250.00'
I have these strings: "59.50" & "30.00"
What I need to do is convert them to integers but keep the trailing zeros at the end to effectively return:
59.50
30.00
I've tried:
Math.round(59.50 * 1000) / 1000
Math.round(30.00 * 1000) / 1000
but ended up with
59.5
30
I'm assuming I need to use a different method than Math.round as this automatically chops off trailing zeros.
I need to keep these as integers as they need to be multiplied with other integers and keep two decimals points. T thought this would be fairly straight forward but after a lot of searching I can't seem to find a solution to exactly what I need.
Thanks!
Your premise is flawed. If you parse a number, you are converting it to its numerical representation, which by definition doesn't have trailing zeros.
A further flaw is that you seem to think you can multiply two numbers together and keep the same number of decimal places as the original numbers. That barely makes sense.
It sounds like this might be an XY Problem, and what you really want to do is just have two decimal places in your result.
If so, you can use .toFixed() for this:
var num = parseFloat("59.50");
var num2 = parseFloat("12.33");
var num3 = num * num2
console.log(num3.toFixed(2)); // 733.64
Whenever you want to display the value of the variable, use Number.prototype.toFixed(). This function takes one argument: the number of decimal places to keep. It returns a string, so do it right before viewing the value to the user.
console.log((123.4567).toFixed(2)); // logs "123.46" (rounded)
To keep the decimals - multiply the string by 1
example : "33.01" * 1 // equals to 33.01
Seems you are trying to retain the same floating point, so better solution will be some thing like
parseFloat(string).toFixed(string.split('.')[1].length);
If you want numbers with decimal points, you are not talking about integers (which are whole numbers) but floating point numbers.
In Javascript all numbers are represented as floating point numbers.
You don't need the trailing zeros to do calculations. As long as you've got all the significant digits, you're fine.
If you want to output your result with a given number of decimal values, you can use the toFixed method to transform your number into a formatted string:
var num = 1.5
var output = num.toFixed(2) // '1.50'
// the number is rounded
num = 1.234
output = num.toFixed(2) // '1.23'
num = 1.567
output = num.toFixed(2) // '1.57'
Here's a more detailed description of toFixed: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed
Using Javascript Math I can convert a decimal number like 100 into decimal power number like 1e+2
Math.pow(10, 2)
But how can I do it the other way round? How can I convert a decimal power like 1e+2 to a regular decimal like 100? I need this to save a number in a database number column.
I could not find any method or jquery plugin that will do this for me.
The expression you showed above, Math.pow(10, 2), actually evaluates to 100.
But if you are given the string 1e+2, you can change it into 100 by calling parseFloat():
var s = '1e+2', // This is a string in scientific notation.
x = parseFloat(s); // Here we convert it to the more widespread notation.
document.write('"'+s+'" -> '+x); // Let's print out the values for testing purposes.
What you are talking about is number formats, not numbers.
The string "100" is the textual representation of the number 100. The string "1e+2" is the textual representation of the same number, but in scientific format.
A numeric value doesn't have any specific format. The values in the variables a, b and c in this code are completely identical:
var a = 100;
var b = Math.pow(10, 2);
var c = 1e+2;
A numeric value only gets a specific format when you create a textual represenation of the number. I this code the variables from the previous example are displayed as text:
console.log(a);
console.log(b);
console.log(c);
As the values are not to small or too large to be resonably represented in the regular decimal format, that's how they come out:
100
100
100
When you want to store a numeric value in the database, it doesn't matter where the number came from, it's just the numeric value itself that is used.
Math.pow(x, y) actually returns the result of x^y. In your specific case, it is being represented in scientific notation, but the actual number is still being 100.
If you have a string and want to get the actual number, you can use:
Number("1e+2")
Example
$("#result").append(Number("1e+2"));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result"></div>
I have a number
For example:
8183
What I need is to convert it to a float number-
For example 8183
(8183).toFixed(2);
will return me
8183.00
But I need to truncate it further, so the final number will be
8.18
So basically I need to make it float number with just 2 decimal places.
I tried using the Math.floor and ceil but couldnt figure it out!
Well what you're trying to accomplish is not completely clear, but I think that if you start by dividing by 1000, then call toFixed on it, it will give you the desired result.
var before = 8183;
var after = (before / 1000).toFixed(2); //8.18
You could divide by 10 until you are less than 10:
var digits = 8183;
while((digits = digits/10) > 10) {}
digits = digits.toFixed(2); // 8.18
For negative numbers, you could want to store a boolean value and use Math.abs(digits).
For numbers less than 0, you would want to multiple instead of divide.
If all you really want is scientific notation use toExponential(2)
In the interest of creating cross-platform code, I'd like to develop a simple financial application in JavaScript. The calculations required involve compound interest and relatively long decimal numbers. I'd like to know what mistakes to avoid when using JavaScript to do this type of math—if it is possible at all!
You should probably scale your decimal values by 100, and represent all the monetary values in whole cents. This is to avoid problems with floating-point logic and arithmetic. There is no decimal data type in JavaScript - the only numeric data type is floating-point. Therefore it is generally recommended to handle money as 2550 cents instead of 25.50 dollars.
Consider that in JavaScript:
var result = 1.0 + 2.0; // (result === 3.0) returns true
But:
var result = 0.1 + 0.2; // (result === 0.3) returns false
The expression 0.1 + 0.2 === 0.3 returns false, but fortunately integer arithmetic in floating-point is exact, so decimal representation errors can be avoided by scaling1.
Note that while the set of real numbers is infinite, only a finite number of them (18,437,736,874,454,810,627 to be exact) can be represented exactly by the JavaScript floating-point format. Therefore the representation of the other numbers will be an approximation of the actual number2.
1 Douglas Crockford: JavaScript: The Good Parts: Appendix A - Awful Parts (page 105).
2 David Flanagan: JavaScript: The Definitive Guide, Fourth Edition: 3.1.3 Floating-Point Literals (page 31).
Scaling every value by 100 is the solution. Doing it by hand is probably useless, since you can find libraries that do that for you. I recommend moneysafe, which offers a functional API well suited for ES6 applications:
const { in$, $ } = require('moneysafe');
console.log(in$($(10.5) + $(.3)); // 10.8
https://github.com/ericelliott/moneysafe
Works both in Node.js and the browser.
There's no such thing as "precise" financial calculation because of just two decimal fraction digits but that's a more general problem.
In JavaScript, you can scale every value by 100 and use Math.round() everytime a fraction can occur.
You could use an object to store the numbers and include the rounding in its prototypes valueOf() method. Like this:
sys = require('sys');
var Money = function(amount) {
this.amount = amount;
}
Money.prototype.valueOf = function() {
return Math.round(this.amount*100)/100;
}
var m = new Money(50.42355446);
var n = new Money(30.342141);
sys.puts(m.amount + n.amount); //80.76569546
sys.puts(m+n); //80.76
That way, everytime you use a Money-object, it will be represented as rounded to two decimals. The unrounded value is still accessible via m.amount.
You can build in your own rounding algorithm into Money.prototype.valueOf(), if you like.
Unfortunately all of the answers so far ignore the fact that not all currencies have 100 sub-units (e.g., the cent is the sub-unit of the US dollar (USD)). Currencies like the Iraqi Dinar (IQD) have 1000 sub-units: an Iraqi Dinar has 1000 fils. The Japanese Yen (JPY) has no sub-units. So "multiply by 100 to do integer arithmetic" isn't always the correct answer.
Additionally for monetary calculations you also need to keep track of the currency. You can't add a US Dollar (USD) to an Indian Rupee (INR) (without first converting one to the other).
There are also limitations on the maximum amount that can be represented by JavaScript's integer data type.
In monetary calculations you also have to keep in mind that money has finite precision (typically 0-3 decimal points) & rounding needs to be done in particular ways (e.g., "normal" rounding vs. banker's rounding). The type of rounding to be performed might also vary by jurisdiction/currency.
How to handle money in javascript has a very good discussion of the relevant points.
In my searches I found the dinero.js library that addresses many of the issues wrt monetary calculations. Haven't used it yet in a production system so can't give an informed opinion on it.
use decimaljs ... It a very good library that solves a harsh part of the problem ...
just use it in all your operation.
https://github.com/MikeMcl/decimal.js/
Your problem stems from inaccuracy in floating point calculations. If you're just using rounding to solve this you'll have greater error when you're multiplying and dividing.
The solution is below, an explanation follows:
You'll need to think about mathematics behind this to understand it. Real numbers like 1/3 cannot be represented in math with decimal values since they're endless (e.g. - .333333333333333 ...). Some numbers in decimal cannot be represented in binary correctly. For example, 0.1 cannot be represented in binary correctly with a limited number of digits.
For more detailed description look here: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
Take a look at the solution implementation: http://floating-point-gui.de/languages/javascript/
Due to the binary nature of their encoding, some decimal numbers cannot be represented with perfect accuracy. For example
var money = 600.90;
var price = 200.30;
var total = price * 3;
// Outputs: false
console.log(money >= total);
// Outputs: 600.9000000000001
console.log(total);
If you need to use pure javascript then you have need to think about solution for every calculation. For above code we can convert decimals to whole integers.
var money = 60090;
var price = 20030;
var total = price * 3;
// Outputs: true
console.log(money >= total);
// Outputs: 60090
console.log(total);
Avoiding Problems with Decimal Math in JavaScript
There is a dedicated library for financial calculations with great documentation. Finance.js
Use this code for currency calculation and round numbers in two digits.
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript Variables</h1>
<p id="test1"></p>
<p id="test2"></p>
<p id="test3"></p>
<script>
function setDecimalPoint(num) {
if (isNaN(parseFloat(num)))
return 0;
else {
var Number = parseFloat(num);
var multiplicator = Math.pow(10, 2);
Number = parseFloat((Number * multiplicator).toFixed(2));
return (Math.round(Number) / multiplicator);
}
}
document.getElementById("test1").innerHTML = "Without our method O/P is: " + (655.93 * 9)/100;
document.getElementById("test2").innerHTML = "Calculator O/P: 59.0337, Our value is: " + setDecimalPoint((655.93 * 9)/100);
document.getElementById("test3").innerHTML = "Calculator O/P: 32.888.175, Our value is: " + setDecimalPoint(756.05 * 43.5);
</script>
</body>
</html>