I want a function that can take a number (say 1000.43) and return the tens, hundreds, thousands, and decimal part. So in 1000.43, it would maybe return an array with [1000, 0, 0, .43]
. I know it sounds hard but how would I do that. Maybe you can give me some advice on how to do that or can supply me with the code. Either way is greatly appreciated.

- 94,763
- 41
- 167
- 253
-
1For 1000.43, wouldn't the array be `[1000, 0, 0, .43]`? And what about the one's place? – FishBasketGordo Feb 25 '12 at 16:31
-
what would be the 1234.234 be - do you need to split the decimal part into tenth/hundriedth/thousandths? Would it be [1000, 200, 30, 4, .234] ? – Roman Goyenko Feb 25 '12 at 16:34
-
Actually, it would be `[1,0,0,.43]`. – Abhranil Das Feb 25 '12 at 16:35
-
Related: http://stackoverflow.com/questions/3179783/php-leftmost-digit – Incognito Feb 25 '12 at 16:39
5 Answers
Start with a string to get a consistent picture of your number without further worrying about floating point, which is more complicated than it sounds:
const toDecimal = (n) => {
if (!Number.isFinite(n)) {
throw new RangeError("number must be finite");
}
// ToString(n) may be of the form …e±…
let [significand, exponent] = String(n).split("e");
if (exponent === undefined) {
return significand.includes(".")
? significand
: significand + ".0";
}
const [integerPart, fractionalPart = ""] = significand.split(".");
const integerDigits = [...integerPart];
const fractionalDigits = [...fractionalPart].reverse();
exponent = Number(exponent);
while (exponent > 0) {
integerDigits.push(fractionalDigits.pop() ?? "0");
exponent--;
}
while (exponent < 0) {
fractionalDigits.push(integerDigits.pop() ?? "0");
exponent++;
}
return `${integerDigits.join("") || "0"}.${fractionalDigits.reverse().join("") || "0"}`;
};
(If you are starting or can start with a decimal string of the right form, you should skip this toDecimal
step and just use the string directly.)
After that, the value of each digit of the integer part can be determined by its position relative to the decimal point (i.e. the end of the integer part).
const toDigitsAndFractional = (n) => {
const [integerPart, fractionalPart] = toDecimal(n).split(".");
const result = Array.from(integerPart,
(c, i) => 10 ** (integerPart.length - i - 1) * Number(c));
result.push("." + fractionalPart);
return result;
};
const toDecimal = (n) => {
if (!Number.isFinite(n)) {
throw new RangeError("number must be finite");
}
// ToString(n) may be of the form …e±…
let [significand, exponent] = String(n).split("e");
if (exponent === undefined) {
return significand.includes(".")
? significand
: significand + ".0";
}
const [integerPart, fractionalPart = ""] = significand.split(".");
const integerDigits = [...integerPart];
const fractionalDigits = [...fractionalPart].reverse();
exponent = Number(exponent);
while (exponent > 0) {
integerDigits.push(fractionalDigits.pop() ?? "0");
exponent--;
}
while (exponent < 0) {
fractionalDigits.push(integerDigits.pop() ?? "0");
exponent++;
}
return `${integerDigits.join("") || "0"}.${fractionalDigits.reverse().join("") || "0"}`;
};
const toDigitsAndFractional = (n) => {
const [integerPart, fractionalPart] = toDecimal(n).split(".");
const result = Array.from(integerPart,
(c, i) => 10 ** (integerPart.length - i - 1) * Number(c));
result.push("." + fractionalPart);
return result;
};
console.log(JSON.stringify(toDigitsAndFractional(1000.43)));
console.log(JSON.stringify(toDigitsAndFractional(4314.23)));
console.log(JSON.stringify(toDigitsAndFractional(1000.43e+20)));
console.log(JSON.stringify(toDigitsAndFractional(1000.43e-20)));
.as-console-row-code {
word-break: break-word;
}

- 218,210
- 55
- 464
- 476
-
-
When I do `splitToParts(4314.23);` it gives me `[4000, 300, 10, 4, 0.22999999999956344]` – David G Feb 25 '12 at 16:41
-
1JavaScript doesn't work well with floating point numbers. String operations might be preferred in this case, since `splitToParts(10.43)` returns `[10, 0.4299999999999997]`. – Rob W Feb 25 '12 at 16:42
-
@David: Yeah, the standard can't accurately represent certain numbers. You'll have to round them to something reasonable. – Ry- Feb 25 '12 at 16:43
-
The standard? What are you talking about? `.23` can be represented **perfectly** accurately by every standard-compliant javascript implementation. If your solution is inaccurate then that's a different story. – davin Feb 25 '12 at 16:52
-
@davin: No, the double representation of 0.23 doesn’t correspond to exactly 0.23. – Ry- Nov 08 '22 at 00:34
You could use Modulo (%) like this
var num = 1573.64;
var th = Math.floor((num % 10000) / 1000),
h = Math.floor((num % 1000) / 100),
t = Math.floor((num % 100) / 10),
u = Math.floor(num % 10),
d = num % 1;
console.log(th, h, t, u, d);
Writing as a function it could be something like
function splitNumber(num) {
var len = num.toString().split('.')[0].length, //get length above decimal point
d = Math.pow(10, len),
a = [];
for (var i = 0; i < len+1; i++) {
var x = num % d;
if (d > 1) {
d /= 10;
a.push(Math.floor(x / d));
} else {
//below decimal point
a.push(x);
}
}
return a;
}

- 2,059
- 17
- 23
This is the shortest yet complete implementation:
function parts(d) {
var num = (d+'').split('.')
, array = Array.prototype.slice.call(num[0])
, zeros = '';
for (var i = array.length-2; 0 <= i; i--) {
zeros += '0';
if (array[i] !== '0') array[i] = array[i] + zeros;
}
if (num[1]) array.push('.' + num[1]);
return array;
}
// Example:
parts(10.4); // [10, 0, .4]

- 341,306
- 83
- 791
- 678
-
1It's not the shortest, and it doesn't come close to what the OP was looking for. `["1", "0", "0", "0", 0.42999999999995] !== [1000, 0, 0, .43]` – davin Feb 25 '12 at 16:43
-
I need it to return the hundreds, tens, and ones. So I mean, from your example, `parts(10.4)` should return `[10, 0, .4];` – David G Feb 25 '12 at 16:44
-
@RobW, you're kidding right? What makes you think the OP was replying to you? There are two other comments there, and evidence (an edit from the OP on the question) suggests that he is agreeing to *another* comment. – davin Feb 25 '12 at 16:49
-
1@davin The OP didn't reply to me, except for at this answer. I pointed to the question's comment to show how I constructed the initial answer. – Rob W Feb 25 '12 at 16:50
First check for a .
and split the string on that. If their is a decimal add it to the array. Then loop backwards adding each number to the beginning of the array using unshift
Also in your loop if you have your counter starting at zero then that number is how many zeroes you will have to add to number. So some sample code.
var num = '1234.5';
var arr=[];
num = num.split('.');
if(num[1]!==''){
arr.unshift(num[1]);
}
part=num[0],len=part.length,zeroes='000000000000';
for(var i=0;i<len;i++){
var digit = part.substr(len-i-1,1);
arr.unshift(digit+zeroes.slice(0,i));
}

- 6,236
- 6
- 33
- 62
It ought to be simple- how many units, tens, hundreds, thousands...
just watch for decimals floating off on you.
function tithe(n){
if(!isFinite(n)) return NaN;
n= Math.abs(n);
var A= [], I= Math.floor(n),
dec= String(n).split('.')[1],
x= 1, t;
while(I/x> 0){
t= I%(x*= 10);
I-= t;
A.unshift(t);
}
if(dec) A.push(+dec);
return A;
}
tithe(12022045.554)
/* returned value: (Array)
10000000,2000000,0,20000,2000,0,40,5,554
*/

- 102,654
- 32
- 106
- 127