This question already has answers here:
How do I split a string, breaking at a particular character?
(17 answers)
Closed 9 months ago.
I am making a calculator where user can past numbers with spaces like
20 30 40 60 50
and it will calculate all in total = 200
How I can convert this string "20 30 40 60 50" to Numbers with spaces? Because I'll than replace the space with +
You can use split with map for transform string to number then use reduce for sum array like:
const string = '20 30 40 60 50';
const arrayNumbers = string.split(' ').map(el => parseInt(el));
const sum = arrayNumbers.reduce((sumCounter, a) => sumCounter + a, 0);
console.log(arrayNumbers, sum);
Please note: If you plan to use decimals use parseFloat instead of parseInt
Reference:
String.prototype.split()
Array.prototype.map()
Array.prototype.reduce()
Related
Let's say that I have a list of points declared in this format: x1,y1 x2,y2
listOfPoints : string = "12.2, 13.0 198.2, 141";
What could I do to multiply by 1.5, for example, every number of this string ?
Do I need to iterate over the listOfPoints and extract a string every time that there is a ', ' or ' ', convert that string into a number, multiply it by 1.5 and reconvert it into a string to finally put it into a new string (newListOfPoints) ?
Or is there a different way to that more efficiently ?
Thank you.
Use a regular expression with a replacer function to match digits, possibly with decimals, and replace with those digits multiplied by the number you want:
const listOfPoints = "12.2, 13.0 198.2, 141";
const multiplied = listOfPoints.replace(
/\d+(?:\.\d+)?/g,
match => match * 1.5
);
console.log(multiplied);
Due to floating-point issues, some of the resulting numbers may have trailing digits. If you don't want that, you can round the multiplied number to a certain number of decimal places:
const listOfPoints = "12.2, 13.0 198.2, 141";
const multiplied = listOfPoints.replace(
/\d+(?:\.\d+)?/g,
match => Math.round(1000 * match * 1.5) / 1000
);
console.log(multiplied);
I need to generate 26 digit numbers with Math.random, but when I use this:
Math.floor(Math.random() * 100000000000000000000000000) + 900000000000000000000000000
I gets 9.544695043285823e+26
Modern browsers support BigInt and bigint primitive type and we can combine it with a random generated array containing 8 bytes (the sizeof bigint is 8 bytes (64 bits)).
1. Generating Random BigInt Performance Wise
We can generate a random hex string of 16 characters length and apply it directly to BigInt:
const hexString = Array(16)
.fill()
.map(() => Math.round(Math.random() * 0xF).toString(16))
.join('');
const randomBigInt = BigInt(`0x${hexString}`);
// randomBigInt will contain a random Bigint
document.querySelector('#generate').addEventListener('click', () => {
const output = [];
let lines = 10;
do {
const hexString = Array(16)
.fill()
.map(() => Math.round(Math.random() * 0xF).toString(16))
.join('');
const number = BigInt(`0x${hexString}`);
output.push(`${
number.toString().padStart(24)
} : 0x${
hexString.padStart(16, '0')
}`);
} while (--lines > 0);
document.querySelector('#numbers').textContent = output.join('\n');
});
<button id="generate">Generate</button>
<pre id="numbers"><pre>
2. Generating Random BigInt from random bytes array
If we want to use Uint8Array or if we want more control over the bits manipulation, we can combine Array.prototype.fill with Array.prototype.map to generate an array containing 8 random byte number values (beware this is around 50% slower than the above method):
const randomBytes = Array(8)
.fill()
.map(() => Math.round(Math.random() * 0xFF));
// randomBytes will contain something similar to this:
// [129, 59, 98, 222, 20, 7, 196, 244]
Then we use Array.prototype.reduce to initialize a BigInt of zero value and left shift each randum byte value its position X 8 bits and applying bitwise or to the current value of each reduce iteration:
const randomBigInt = randomBytes
.reduce((n, c, i) => n | BigInt(c) << BigInt(i) * 8n, 0n);
// randomBigInt will contain a random Bigint
Working example generating 10 random BigInt values
document.querySelector('#generate').addEventListener('click', () => {
const output = [];
let lines = 10;
do {
const number = Array(8)
.fill()
.map(() => Math.round(Math.random() * 0xFF))
.reduce((n, c, i) => n | BigInt(c) << BigInt(i) * 8n, 0n);
output.push(`${
number.toString().padStart(24)
} : 0x${
number.toString(16).padStart(16, '0')
}`);
} while (--lines > 0);
document.querySelector('#numbers').textContent = output.join('\n');
});
<button id="generate">Generate</button>
<pre id="numbers"><pre>
Floating point numbers in JavaScript (and a lot of other languages) can contain only about 15.955 digits without losing precision. For bigger numbers you can look into JS libraries, or concatenate few numbers as strings. For example:
console.log( Math.random().toString().slice(2, 15) + Math.random().toString().slice(2, 15) )
Your question seems to be an XY problem where what you really want to do is generate a sequence of 26 random digits. You don't necessarily have to use Math.random. Whenever one mentions randomness it's important to specify how that randomness is distributed, otherwise you could end up with a paradox.
I'll assume you want each of the 26 digits to be independently randomly chosen uniformly from each of the 10 digits from 0 to 9, but I can also see a common interpretation being that the first digit must not be 0, and so that digit would be chosen uniformly from numbers 1 to 9.
Other answers may tempt you to choose a random bigint value using what amounts to random bits, but their digits will not be randomly distributed in the same way, since their maximum value is not a power of 10. For a simple example consider that a random 4 bit binary value in decimal will range from 00 to 15, and so the second digit will have a 12/16(=75%) chance of being 0 to 5, though it should be 60%.
As for an implementation, there's many ways to go about it. The simplest way would be to append to a string 26 times, but there are more potentially efficient ways that you could investigate for yourself if you find the performance isn't adequate. Math.random has a roughly uniform distribution from 0 to 1, but by being double precision it only has 15 or so significant decimal digits to offer us, so for each call to Math.random we should be able to retrieve up to 15 out of 26 decimal digits. Using this fact, I would suggest the following compromise on ease of readability and efficiency:
function generate26Digits() {
const first13 = Math.floor(Math.random() * Math.pow(10, 13)).toFixed(0).padStart(13, "0");
const next13 = Math.floor(Math.random() * Math.pow(10, 13)).toFixed(0).padStart(13, "0");
return first13 + next13;
}
console.log(generate26Digits())
This solution is not cryptographically secure however, and so I will direct readers to use Crypto.getRandomValues if you need more security for this for some reason.
If you then want to do math on this number as well without losing precision, you will have to use bigint types as others have suggested.
If I use a 6 decillion LG about 72.9 million out of 300 but when I switch to 10 centillion it comes like this 10 ^ 999 - 99999 + 26 just like how 9 - 9 - 9 - 9 - googolplex is equal to 0 googolplex
This question already has answers here:
Why does floating-point arithmetic not give exact results when adding decimal fractions?
(31 answers)
Closed 4 years ago.
I have the following numerical array:
var numberArray: number[] = [2.15, 0.72, 2.15, 0.72, 0.72];
where the sum of the values is 6.46. However, if I also run:
var Total = numberArray.reduce(function(a, b) {return a + b;});
I always get 6.459999999999999.
I have a numerical array with about 1000 values and when I try and get the total of these my numbers are way off and I think this is the reason. How can I get this to aggregate properly?
The toFixed() method formats a number using fixed-point notation.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed
const numberArray: number[] = [2.15, 0.72, 2.15, 0.72, 0.72];
const Total = numberArray.reduce((a, b) => {return a + b;});
console.log(Total.toFixed(2));
This question already has answers here:
Remove insignificant trailing zeros from a number?
(23 answers)
How to format a float in javascript?
(14 answers)
Closed 5 years ago.
I have a series of numbers. For example:
3, 3.4567, 4.5, 5.72, 6.12345
How can I show original numbers if they are integers or they have no more than 3 digits after the decimal point and show max 3 digits after the decimal point if there are more than 3? Here is what I want:
3, 3.456, 4.5, 5.72, 6.123
I used toFixed(), but it makes each number come with 3 digits after the decimal point.
Is there any Javascript method to use to achieve what I want?
--------- update -----------
I used this from the pointer:
Math.round(original*1000)/1000
from the old post. It seems working.
You can use Number.prototype.toPrecision() to round to nearest 3 digits after decimal point, then parseFloat() the result:
var num = 6.12345;
var precise = num.toPrecision(4); //"6.123"
var result = parseFloat(precise); //6.123
var num = 4.5;
var precise = num.toPrecision(4); //"4.500"
var result = parseFloat(precise); //4.5
If these numbers are in an array, you can create a function customPrecision to map:
function customPrecision(num) {
return parseFloat(num.toPrecision(4));
}
var nums = [3, 3.4567, 4.5, 5.72, 6.12345];
var preciseNums = nums.map(customPrecision); //[3, 3.457, 4.5, 5.72, 6.123]
Just cast the fixed strings back into numbers using the unary + operator before printing them:
var floats = [3, 3.4567, 4.5, 5.72, 6.12345]
function toMax3Decimals (x) {
return +x.toFixed(3)
}
console.log(floats.map(toMax3Decimals))
Not sure this is the best way, but it works
Math.floor(3.4567*1000)/1000
Math.floor(6.12345*1000)/1000
I'm trying to random 8 digits number 0-7 , but without the 8 and 9
this is what I've done, but I can't exclude the 8 and 9
var b = Math.floor(Math.random()*90000000) + 10000000;
console.log(b)
is there any quick for random the exact 8 digits exclude number? or do I really have to random one by one and += until 8 digits ?
Convert to octal (which contains only the digits 0-7) and trim to the desired length:
b.toString(8).substr(0, 8)
You could get first the max number of the octal system with 8 places and use the decimal system for generating the random value and convert it back to the wanted system.
var max = parseInt(100000000, 8);
console.log(('0000000' + Math.floor(Math.random() * max).toString(8)).slice(-8));
You need a number of 8 digits in base 8.
This means you're looking for a (decimal) number between 8^7 and 8^8-1, converted to base 8.
This should do the trick :
// initialize min and max values
var vmin = Math.pow(8,7);
var vmax = Math.pow(8,8)-1;
// compute random number within range
var dec = Math.floor(Math.random()*(vmax-vmin))+vmin;
// convert to base 8
console.log(dec.toString(8));
Perhaps you would want something more like this:
var b = Math.floor(Math.random()*8);
console.log(b);