Using arrays to do basic calculations with negative exponent - javascript

I'm trying to write a function which outputs the correct result when multiplying a number by a negative power of ten using arrays and split() method. For example the following expressions get the right result: 1x10^-2 = 0.01 1x10^-4 = 0.0001.
Problem comes when the number's length is superior to the exponent value (note that my code treats num as a string to split it in an array as shown in code bellow :
//var num is treated as a string to be splited inside get_results() function
//exponent is a number
//Try different values for exponent and different lengths for num to reproduce the problem
//for example var num = 1234 and var exponent = 2 will output 1.234 instead of 12.34
var num = '1';
var sign = '-';
var exponent = 2;
var op = 'x10^'+sign+exponent;
var re = get_result(num);
console.log(num+op +' = '+ re);
function get_result(thisNum) {
if (sign == '-') {
var arr = [];
var splitNum = thisNum.split('');
for (var i = 0; i <= exponent-splitNum.length; i++) {
arr.push('0');
}
for (var j = 0; j < splitNum.length; j++) {
arr.push(splitNum[j]);
}
if (exponent > 0) {
arr.splice(1, 0, '.');
}
arr.join('');
}
return arr.join('');
}
Demo here : https://jsfiddle.net/Hal_9100/c7nobmnj/
I tried different approaches to get the right results with different num lengths and exponent values, but nothing I came with worked and I came to the point where I can't think of anything else.
You can see my latest try here : https://jsfiddle.net/Hal_9100/vq1hrru5/
Any idea how I could solve this problem ?
PS: I know most of the rounding errors due to javascript floating point conversion are pretty harmless and can be fixed using toFixed(n) or by using specialized third-party librairies, but my only goal here is to get better at writing pure javascript functions.

I am not sure if you want to keep going with the array approach to a solution, but it seems like this could be solved with using the Math.pow() method that already exists.
function computeExponentExpression ( test ) {
var base;
var multiplier;
var exponent;
test.replace(/^(\d+)(x)(\d+)([^])([-]?\d+)$/, function() {
base = parseInt(arguments[1], 10);
multiplier = parseInt(arguments[3], 10);
exponent = parseInt(arguments[5], 10);
return '';
} );
console.log( base * Math.pow(multiplier, exponent));
}
computeExponentExpression('1x10^-4');
computeExponentExpression('1x10^2');
computeExponentExpression('4x5^3');

The problem is where you push the decimal point .
instead of
arr.splice(1, 0, '.');
try this:
arr.splice(-exponent, 0, '.');
See fiddle: https://jsfiddle.net/free_soul/c7nobmnj/1/

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

Spliting the binary string in half

I am trying to split binary number in half and then just add 4 zeroes.
For example for 10111101 I want to end up with only the first half of the number and make the rest of the number zeroes. What I want to end up would be 10110000.
Can you help me with this?
Use substring to split and then looping to pad
var str = '10111101';
var output = str.substring( 0, str.length/2 );
for ( var counter = 0; counter < str.length/2; counter++ )
{
output += "0";
}
alert(output)
try this (one-liner)
var binary_str = '10111101';
var padded_binary = binary_str.slice(0, binary_str.length/2) + new Array(binary_str.length/2+1).join('0');
console.log([binary_str,padded_binary]);
sample output
['10111101','10110000']
I guess you are using JavaScript...
"10111101".substr(0, 4) + "0000";
It's a bit unclear if you are trying to operate on numbers or strings. The answers already given do a good job of showing how to operate on a strings. If you want to operate with numbers only, you can do something like:
// count the number of leading 0s in a 32-bit word
function nlz32 (word) {
var count;
for (count = 0; count < 32; count ++) {
if (word & (1 << (31 - count))) {
break;
}
}
return count;
}
function zeroBottomHalf (num) {
var digits = 32 - nlz32(num); // count # of digits in num
var half = Math.floor(digits / 2);// how many to set to 0
var lowerMask = (1 << half) - 1; //mask for lower bits: 0b00001111
var upperMask = ~lowerMask //mask for upper bits: 0b11110000
return num & upperMask;
}
var before = 0b10111101;
var after = zeroBottomHalf(before);
console.log('before = ', before.toString(2)); // outputs: 10111101
console.log('after = ', after.toString(2)); // outputs: 10110000
In practice, it is probably simplest to covert your number to a string with num.toString(2), then operate on it like a string as in one of the other answers. At the end you can convert back to a number with parseInt(str, 2)
If you have a real number, not string, then just use binary arithmetic. Assuming your number is always 8 binary digits long - your question is kinda vague on that - it'd be simply:
console.log((0b10111101 & 0b11110000).toString(2))
// 10110000

how to round up if value is two decimal and format as 3 decimals in javascript?

Test cases:
var num1 = 10.66;
var num2 = 10.7898
The function I found on stackOverFlow:
function formatUserCurrencyValue(fieldValue){
var num = parseFloat(fieldValue);
var str = num.toFixed(10);
str = str.substring(0, str.length-7);
return str;
};
I would like the result to be like this: if 10.66 then 10.670 and if 10.78998 then 10.789. Basically if the value has 2 decimal places then the result should round up the first and then format as 3 decimals. If more than 2 decimals (eg. 10.78998) then 10.789, trimming out values after 3 decimals.
Could somebody please tell me how I can achieve this? I tried with the above function as well as some others I found but the result is not what I expected for the 10.66 scenario. I am getting 10.660 instead of 10.670.
It looks like a similar question has already been asked here: Formatting a number with exactly two decimals in JavaScript
I liked the answer that #Miguel had. Using a function to do the conversion.
function precise_round(num, decimals) {
var t=Math.pow(10, decimals);
return (Math.round((num * t) + (decimals>0?1:0)*(Math.sign(num) * (10 / Math.pow(100, decimals)))) / t).toFixed(decimals);
}
Then use the function.
precise_round(num,3)
Setting aside the fact that rounding num1 will produce 10.66 and not 10.67 what you want can be achieved with the below function which will print the appropriate results to the console.
var num1 = 10.66;
var num2 = 10.7898;
var roundIt = function(num) {
console.log(parseFloat(Math.round(num * 1000) / 1000).toFixed(3));
};
roundIt(num2); //10.790
roundIt(num1); //10.660
Since using the toFixed() method returns a string we wrap the result in parseFloat() so that we get a floating point number.
Here you have what you ask, it seems weird to me. Round all like this is something "special" at least... but, is exactly what you ask.
var weirdRound = function(n) {
var splited = n.toString().split(".");
var res = 0;
if(splited[1]) {
var len = splited[1].length;
if(len > 3) {
splited[1] = splited[1].substr(0, 3);
res = (splited.join(".") *1).toFixed(3);
} else if(len == 2) {
splited[1] = splited[1].substr(0, 1) + ((splited[1].substr(len -1, len) *1) +1);
res = (splited.join(".") *1).toFixed(3);
} else if(len == 1) {
res = n.toFixed(2)
} else {
res = n.toFixed(3);
}
}
return res.toFixed(3);
}
console.log(weirdRound(10.66));
console.log(weirdRound(10.9));
console.log(weirdRound(10.7898));
console.log(weirdRound(1.12));
console.log(weirdRound(1.12565));
console.log(weirdRound(1.125));

how to divide a number a in a series of all whole numbers?

Hi sorry for asking this if this is a stupid question.
I would like to ask how to securely divide a number in Javascript that it will always
output the result in a way that it will output pure whole numbers.
example:
10 / 2 ---> 5, 5 ( it would be 2 fives so it is whole number )
BUT
10 / 3 ---> 3, 3, 4 ( it would have two 3 and one 4 so that it would still result to 10 )
10/3 will give you 3.333333..., never four... if you want to check is a number will give you "whole numbers" as you say, use modulo (%).
Modulo finds the remainder of division of one number by another.
For example
10%5 = 0 because 10 divided by 5 is a "whole number"
10%3 = 1 because the closest 10/3 is 3... 3x3=9... 10-9=1
So in your code, if you want to know if a number divided by another number is whole, you need to do
if (number1%number2 == 0) { ... }
Read more about it here
EDIT :
I read your question again and I think this fiddle is what you want
var number1 = 10,
number2 = 3;
if (number1 / number2 == 0) {
alert('the numbers are whole');
} else {
var remainder = number1%number2;
var wholes = Math.floor(number1 / number2);
var output = '';
for (var i = 0; i < (wholes - 1); i++) {
output+= number2 + ', ';
}
output += (number2 + remainder);
alert(output);
}
Whatever your result is,just pass it through the parseInt function,For Eg:-
Suppose your answer is 4.3,
The whole number close to it will can be accounted using,
parseInt(4.3)
Which equals 4.
Another posibility: make the number a string and walk all the elements
var a = 11 / 4;
//turn it into a string and remove all non-numeric chars
a = a.toString().replace(/\D/g, '');
//split the string in seperate characters
a = a.split("");
var num = new Array();
//convert back to numbers
for (var i = 0; i < a.length; i++) {
num.push(parseFloat(a[i]));
}
alert(num);
On a sidenote, you'll have to do some kind of rounding, to prevent eternally repeating numbers, like 10/3.
Here is a fiddle
Look at this very simple example:
var x = 10;
var y = 3;
var result = x/y;
var rest = x%y;
for (var i=0; i<y; i++) {
var output;
if(i==y-1){
output = parseInt(result + rest);
}
else{
output = parseInt(result);
}
alert(output);
}
http://jsfiddle.net/guinatal/469Vv/4/

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

Categories