How to sum 2 numbers witout rounding - javascript

I have 2 numbers
a = 1548764548675465486;
b = 4535154875433545787;
when I sum these number they are rounded to
a => 1548764548675465500
b => 4535154875433545700
and a + b returns 6083919424109011000 while it should return 6083919424109011273
is there a javascript solution to solve this problem witout the use of a library ?

To work around the precision limitations associated with JavaScript's numbers, you will need to use a BigInteger library like the popular one offered here: http://silentmatt.com/biginteger/
Usage:
var a = BigInteger("1548764548675465486");
var b = BigInteger("4535154875433545787");
var c = a.add(b);
alert(a.toString() + ' + ' + b.toString() + ' = ' + c.toString());
// Alerts "1548764548675465486 + 4535154875433545787 = 6083919424109011273"
Demo: http://jsfiddle.net/69AEg/1/

There are no integers in Javascript, all numbers are double precision floating point.
That gives you a precision of around 15-16 digits, which is what you are seeing.
as per this question
and potential solution i.e. use a library
Personally, I would not use javascript, never been great at numbers. Just try typing 0.1 + 0.2 into any browsers console window. Result is 0.30000000000000004.
Send the calculation to your server side language (as a string) and do the work there, you should have a better outcome.
Technical article on the nuances of floating point numbers here, if you interested

Well, here is a solution I found witout the use of any external library, all I need to do is to define a class that had a property value wich should be a string, and define the function plus
function LongNumber()
{
// it takes the argument and remove first zeros
this.value = arguments[0].toString();
while(this.value[0]==="0")
this.value = this.value.substr(1);
// this function adds the numbers as string to another string and returns result as LongNumber
this.plus = function (Num)
{
var num1 = pad(Num.value.length, this.value);
var num2 = pad(this.value.length, Num.value);
var numIndex = num1.length;
var rest = 0;
var resultString = "";
while (numIndex)
{
var number1 = parseInt(num1[(numIndex)-1]);
var number2 = parseInt(num2[(numIndex--)-1]);
var addition = (number1+number2+rest)%10;
rest = parseInt((number1+number2+rest)/10);
resultString = addition.toString() + resultString;
}
return new LongNumber((rest?rest.toString():"") + resultString);
}
function pad(width, string)
{
return (width <= string.length) ? string : pad(width, '0' + string)
}
}
All i need to do now is to declare 2 LongNombers and use the function plus
var Number1 = new LongNumber("1548764548675465486");
var Number2 = new LongNumber("4535154875433545787");
var Result = Number1.plus(Number2);
Result.value // returns "6083919424109011273"

Related

How to extract digits after a comma [duplicate]

I am validating a decimal number using JavaScript.
Am just using NaN
var a = 12345.67
Is there any javascript function to get the count or the value itself before and after decimal point .
before() should return 1234
after() should return 67
Please dont suggest a substring!
var a = 12345.67;
alert(a.toString().split(".")[0]); ///before
alert(a.toString().split(".")[1]); ///after
Here is a simple fiddle http://jsfiddle.net/qWtSc/
zzzzBov's suggestion is this
Number.prototype.before = function () {
var value = parseInt(this.toString().split(".")[0], 10);//before
return value ? value : 0;
}
Number.prototype.after = function () {
var value = parseInt(this.toString().split(".")[1], 10);//after
return value ? value : 0;
}
Usage
alert(a.before()); ///before
alert(a.after()); ///after
before is easy. It's just a round down operation.
var before = function(n) {
return Math.floor(n);
};
after is harder without string processing. I mean how would you handle after(Math.PI)? You can't hold a integer with an infinite number of digits after all.
But with some string processing it's easy, just know it won't be exact due to the wonders of floating point math.
var after = function(n) {
var fraction = n.toString().split('.')[1];
return parseInt(fraction, 10);
};
Playing off of other answers... and you wanted a 'numeric' version.. still easiest to convert it to a string and work off the split function...
function getNatural(num) {
return parseFloat(num.toString().split(".")[0]);
}
function getDecimal(num) {
return parseFloat(num.toString().split(".")[1]);
}
var a = 12345.67;
alert(getNatural(a)); ///before
alert(getDecimal(a)); ///after
http://jsfiddle.net/rlemon/qWtSc/1/
var decimalPlaces = 2;
var num = 12345.673
var roundedDecimal = num.toFixed(decimalPlaces);
var intPart = Math.floor(roundedDecimal);
var fracPart = parseInt((roundedDecimal - intPart), 10);
//or
var fractPart = (roundedDecimal - intPart) * Math.pow(10, decimalPlaces);
To find the count/length of characters after dot:
var a = 12345.67;
var after_dot = (a.toString().split(".")[1]).length;
var before_dot= (a.toString().split(".")[0]).length;
Unfortunately there's no way to get the factional part in a reliable way using math functions, because pretty odd roundings often occur, depending on the Javascript engine used.
The best thing to do is to convert it to a string, and then checking if the results is in decimal or scientific notation.
Number.prototype.after = function() {
var string = this.toString();
var epos = string.indexOf("e");
if (epos === -1) { // Decimal notation
var i = string.indexOf(".");
return i === -1 ? "" : n.substring(i + 1);
}
// Scientific notation
var exp = string.substring(epos + 1) - 0; // this is actually faster
// than parseInt in many browsers
var mantix = n.string.substring(0, epos).replace(".", "");
if (exp >= -1) return mantix.substring(exp + 1);
for (; exp < -1; exp++) mantix = "0" + mantix;
return mantix;
}
If your digits after decimal point are fixed, then this solution works without converting to string.
This example shows a solution for 2 digits after decimal.
Before decimal:
const wholeNum = Math.floor(num);
After decimal:
let decimal = (num - wholeNum) * 100

Create a float from two int numbers in JavaScript

How can I construct a float value from two whole values?
var amountBeforeComma = 5;
var amountAfterComma = 234;
var amount = ?? //amount == 5.234
There's the math way, using logarithms:
var amountBeforeComma = 5;
var amountAfterComma = 234;
var amount = amountBeforeComma +
amountAfterComma * Math.pow(10, -(Math.floor(Math.log10(amountAfterComma)) + 1));
console.log(amount);
Math.log10(amountAfterComma) gives us the common logarithm of amountAfterComma, then Math.floor(...) on that gives us the characteristic of it (2 in your example), which is (as the linked Wikipedia page puts it) "how many places the decimal point must be moved so that it is just to the right of the first significant digit". Then we add one to that and make it a negative (e.g., -3 in your example) and raise raise 10 to that power to get a value to multiply it by (0.001 in your example) to put it where it should go. Add the amountBeforeComma and we're done.
Or the string then parse way:
var amountBeforeComma = 5;
var amountAfterComma = 234;
var amount = parseFloat(amountBeforeComma + "." + amountAfterComma);
console.log(amount);
(Or use +(amountBeforeComma + "." + amountAfterComma) to convert with implicit coercion rather than explicit parsing.)
Since no one mentioned... There's the JavaScript way:
var num = +(amountBeforeComma + "." + amountAfterComma);
You can make it by casting numbers to strings and then parsing it as float.
var amount = parseFloat(amountBeforeComma + '.' + amountAfterComma);

Convert string to expression in JavaScript

I am making a calculator in JavaScript and I want to know how to turn a string into an expression.
var numbers = "5+5+6";
numbers = +numbers;
document.querySelector('.screen').innerHTML = numbers;
Adding + before the variable does not seem to work. I would appreciate it if someone helped.
You can use the eval() function like this:
var numbers = "5+5+6";
document.querySelector('.screen').innerHTML = eval(numbers);;
Evaluate/Execute JavaScript code/expressions:
var x = 10;
var y = 20;
var a = eval("x * y") + "<br>";
var b = eval("2 + 2") + "<br>";
var c = eval("x + 17") + "<br>";
var res = a + b + c;
The result of res will be:
200
4
27
Without using eval, which is cheating - you could always write a simple calculator app.
First, take advantage of String.split() as follows
var numbers = "5+5+6";
numbers.split("");
// => ["5","+","5","+","6"]
Now all you need to do is figure out how to evaluate it while keeping the order of operations correct. Hint: it might involve trees.
Try using String.prototype.match() , Array.prototype.reduce() , Number() . See also Chrome App: Doing maths from a string
var numbers = "5+5+6";
var number = numbers.match(/\d+|\+\d+|\-\d+/g)
.reduce(function(a, b) {
return Number(a) + Number(b)
});
document.querySelector(".screen").innerHTML = number;
<div class="screen"></div>

Is there ay JS function to find value before and after decimal point

I am validating a decimal number using JavaScript.
Am just using NaN
var a = 12345.67
Is there any javascript function to get the count or the value itself before and after decimal point .
before() should return 1234
after() should return 67
Please dont suggest a substring!
var a = 12345.67;
alert(a.toString().split(".")[0]); ///before
alert(a.toString().split(".")[1]); ///after
Here is a simple fiddle http://jsfiddle.net/qWtSc/
zzzzBov's suggestion is this
Number.prototype.before = function () {
var value = parseInt(this.toString().split(".")[0], 10);//before
return value ? value : 0;
}
Number.prototype.after = function () {
var value = parseInt(this.toString().split(".")[1], 10);//after
return value ? value : 0;
}
Usage
alert(a.before()); ///before
alert(a.after()); ///after
before is easy. It's just a round down operation.
var before = function(n) {
return Math.floor(n);
};
after is harder without string processing. I mean how would you handle after(Math.PI)? You can't hold a integer with an infinite number of digits after all.
But with some string processing it's easy, just know it won't be exact due to the wonders of floating point math.
var after = function(n) {
var fraction = n.toString().split('.')[1];
return parseInt(fraction, 10);
};
Playing off of other answers... and you wanted a 'numeric' version.. still easiest to convert it to a string and work off the split function...
function getNatural(num) {
return parseFloat(num.toString().split(".")[0]);
}
function getDecimal(num) {
return parseFloat(num.toString().split(".")[1]);
}
var a = 12345.67;
alert(getNatural(a)); ///before
alert(getDecimal(a)); ///after
http://jsfiddle.net/rlemon/qWtSc/1/
var decimalPlaces = 2;
var num = 12345.673
var roundedDecimal = num.toFixed(decimalPlaces);
var intPart = Math.floor(roundedDecimal);
var fracPart = parseInt((roundedDecimal - intPart), 10);
//or
var fractPart = (roundedDecimal - intPart) * Math.pow(10, decimalPlaces);
To find the count/length of characters after dot:
var a = 12345.67;
var after_dot = (a.toString().split(".")[1]).length;
var before_dot= (a.toString().split(".")[0]).length;
Unfortunately there's no way to get the factional part in a reliable way using math functions, because pretty odd roundings often occur, depending on the Javascript engine used.
The best thing to do is to convert it to a string, and then checking if the results is in decimal or scientific notation.
Number.prototype.after = function() {
var string = this.toString();
var epos = string.indexOf("e");
if (epos === -1) { // Decimal notation
var i = string.indexOf(".");
return i === -1 ? "" : n.substring(i + 1);
}
// Scientific notation
var exp = string.substring(epos + 1) - 0; // this is actually faster
// than parseInt in many browsers
var mantix = n.string.substring(0, epos).replace(".", "");
if (exp >= -1) return mantix.substring(exp + 1);
for (; exp < -1; exp++) mantix = "0" + mantix;
return mantix;
}
If your digits after decimal point are fixed, then this solution works without converting to string.
This example shows a solution for 2 digits after decimal.
Before decimal:
const wholeNum = Math.floor(num);
After decimal:
let decimal = (num - wholeNum) * 100

Convert Fraction String to Decimal?

I'm trying to create a javascript function that can take a fraction input string such as '3/2' and convert it to decimal—either as a string '1.5' or number 1.5
function ratio(fraction) {
var fraction = (fraction !== undefined) ? fraction : '1/1',
decimal = ??????????;
return decimal;
});
Is there a way to do this?
Since no one has mentioned it yet there is a quick and dirty solution:
var decimal = eval(fraction);
Which has the perks of correctly evaluating all sorts of mathematical strings.
eval("3/2") // 1.5
eval("6") // 6
eval("6.5/.5") // 13, works with decimals (floats)
eval("12 + 3") // 15, you can add subtract and multiply too
People here will be quick to mention the dangers of using a raw eval but I submit this as the lazy mans answer.
Here is the bare bones minimal code needed to do this:
var a = "3/2";
var split = a.split('/');
var result = parseInt(split[0], 10) / parseInt(split[1], 10);
alert(result); // alerts 1.5
JsFiddle: http://jsfiddle.net/XS4VE/
Things to consider:
division by zero
if the user gives you an integer instead of a fraction, or any other invalid input
rounding issues (like 1/3 for example)
Something like this:
bits = fraction.split("/");
return parseInt(bits[0],10)/parseInt(bits[1],10);
I have a function I use to handle integers, mixed fractions (including unicode vulgar fraction characters), and decimals. Probably needs some polishing but it works for my purpose (recipe ingredient list parsing).
NPM
GitHub
Inputs "2 1/2", "2½", "2 ½", and "2.5" will all return 2.5. Examples:
var numQty = require("numeric-quantity");
numQty("1 1/4") === 1.25; // true
numQty("3 / 4") === 0.75; // true
numQty("¼" ) === 0.25; // true
numQty("2½") === 2.5; // true
numQty("¾") === 0.75; // true
numQty("⅓") === 0.333; // true
numQty("⅔") === 0.667; // true
One thing it doesn't handle is decimals within the fraction, e.g. "2.5 / 5".
I created a nice function to do just that, everything was based off of this question and answers but it will take the string and output the decimal value but will also output whole numbers as well with out errors
https://gist.github.com/drifterz28/6971440
function toDeci(fraction) {
fraction = fraction.toString();
var result,wholeNum=0, frac, deci=0;
if(fraction.search('/') >=0){
if(fraction.search('-') >=0){
wholeNum = fraction.split('-');
frac = wholeNum[1];
wholeNum = parseInt(wholeNum,10);
}else{
frac = fraction;
}
if(fraction.search('/') >=0){
frac = frac.split('/');
deci = parseInt(frac[0], 10) / parseInt(frac[1], 10);
}
result = wholeNum+deci;
}else{
result = fraction
}
return result;
}
/* Testing values / examples */
console.log('1 ',toDeci("1-7/16"));
console.log('2 ',toDeci("5/8"));
console.log('3 ',toDeci("3-3/16"));
console.log('4 ',toDeci("12"));
console.log('5 ',toDeci("12.2"));
Too late, but can be helpful:
You can use Array.prototype.reduce instead of eval
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
ES6
const fractionStrToDecimal = str => str.split('/').reduce((p, c) => p / c);
console.log(fractionStrToDecimal('1/4/2')); // Logs 0.125
console.log(fractionStrToDecimal('3/2')); // Logs 1.5
CJS
function fractionStrToDecimal(str) {
return str.split('/').reduce((p, c) => p / c);
}
console.log(fractionStrToDecimal('1/4')); // Logs 0.25
[EDIT] Removed reducer initial value and now the function works for numerators greater than 1. Thanks, James Furey.
Function (ES6):
function fractionToDecimal(fraction) {
return fraction
.split('/')
.reduce((numerator, denominator, i) =>
numerator / (i ? denominator : 1)
);
}
Function (ES6, condensed):
function fractionToDecimal(f) {
return f.split('/').reduce((n, d, i) => n / (i ? d : 1));
}
Examples:
fractionToDecimal('1/2'); // 0.5
fractionToDecimal('5/2'); // 2.5
fractionToDecimal('1/2/2'); // 0.25
fractionToDecimal('10/5/10'); // 0.2
fractionToDecimal('0/1'); // 0
fractionToDecimal('1/0'); // Infinity
fractionToDecimal('cat/dog'); // NaN
With modern destructuring syntax, the best/safest answer can be simplified to:
const parseFraction = fraction => {
const [numerator, denominator] = fraction.split('/').map(Number);
return numerator / denominator;
}
// example
parseFraction('3/2'); // 1.5
In other words, split the faction by its / symbol, turn both resulting strings into numbers, then return the first number divided by the second ...
... all with only two (very readable) lines of code.
If you don't mind using an external library, math.js offers some useful functions to convert fractions to decimals as well as perform fractional number arithmetic.
console.log(math.number(math.fraction("1/3"))); //returns 0.3333333333333333
console.log(math.fraction("1/3") * 9) //returns 3
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.20.1/math.js"></script>
const fractionStringToNumber = s => s.split("/").map(s => Number(s)).reduce((a, b) => a / b);
console.log(fractionStringToNumber("1/2"));
console.log(fractionStringToNumber("1/3"));
console.log(fractionStringToNumber("3/2"));
console.log(fractionStringToNumber("3/1"));
console.log(fractionStringToNumber("22/7"));
console.log(fractionStringToNumber("355 / 113"));
console.log(fractionStringToNumber("8/4/2"));
console.log(fractionStringToNumber("3")); // => 3, not "3"
From a readability, step through debugging perspective, this may be easier to follow:
// i.e. '1/2' -> .5
// Invalid input returns 0 so impact on upstream callers are less likely to be impacted
function fractionToNumber(fraction = '') {
const fractionParts = fraction.split('/');
const numerator = fractionParts[0] || '0';
const denominator = fractionParts[1] || '1';
const radix = 10;
const number = parseInt(numerator, radix) / parseInt(denominator, radix);
const result = number || 0;
return result;
}
To convert a fraction to a decimal, just divide the top number by the bottom number. 5 divided by 3 would be 5/3 or 1.67. Much like:
function decimal(top,bottom) {
return (top/bottom)
}
Hope this helps, haha
It works with eval() method but you can use parseFloat method. I think it is better!
Unfortunately it will work only with that kind of values - "12.2" not with "5/8", but since you can handle with calculation I think this is good approach!
If you want to use the result as a fraction and not just get the answer from the string, a library like https://github.com/infusion/Fraction.js would do the job quite well.
var f = new Fraction("3/2");
console.log(f.toString()); // Returns string "1.5"
console.log(f.valueOf()); // Returns number 1.5
var g = new Fraction(6.5).div(.5);
console.log(f.toString()); // Returns string "13"
Also a bit late to the party, but an alternative to eval() with less security issues (according to MDN at least) is the Function() factory.
var fraction = "3/2";
console.log( Function("return (" + fraction + ");")() );
This would output the result "1.5" in the console.
Also as a side note: Mixed fractions like 1 1/2 will not work with neither eval() nor the solution with Function() as written as they both stumble on the space.
safer eval() according to MDN
const safeEval = (str) => {
return Function('"use strict";return (' + str + ")")();
}
safeEval("1 1/2") // 1.5
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Do_not_ever_use_eval!
This too will work:
let y = "2.9/59"
let a = y.split('')
let b = a.splice(a.indexOf("/"))
console.log(parseFloat(a.join('')))
a = parseFloat(a.join(''))
console.log(b)
let c = parseFloat(b.slice(1).join(''))
let d = a/c
console.log(d) // Answer for y fraction
I developed a function to convert a value using a factor that may be passed as a fraction of integers or decimals. The user input and conversion factor might not be in the correct format, so it checks for the original value to be a number, as well as that the conversion can be converted to a fraction assuming that /number means 1/number, or there are a numerator and a denominator in the format number/number.
/**
* Convert value using conversion factor
* #param {float} value - number to convert
* #param {string} conversion - factor
* #return {float} converted value
*/
function convertNumber(value, conversion) {
try {
let numberValue = eval(value);
if (isNaN(numberValue)) {
throw value + " is not a number.";
}
let fraction = conversion.toString();
let divider = fraction.indexOf("/");
let upper = 1;
let denominator = 1;
if (divider == -1) {
upper = eval(fraction);
} else {
let split = fraction.split("/");
if (split.length > 2) {
throw fraction + " cannot be evaluated to a fraction.";
} else {
denominator = eval(split[1]);
if (divider > 0) {
upper = eval(split[0]);
}
}
}
let factor = upper/denominator;
if (isNaN(factor)) {
throw fraction + " cannot be converted to a factor.";
}
let result = numberValue * factor;
if (isNaN(result)) {
throw numberValue + " * " + factor + " is not a number.";
}
return result
} catch (err) {
let message = "Unable to convert '" + value + "' using '" + conversion + "'. " + err;
throw message;
}
}
You can use eval() with regex to implement a secure method to calculate fraction
var input = "1/2";
return input.match(/^[0-9\/\.]+$/) != null ? eval(input) : "invalid number";

Categories