Separate integer and decimal part into a number using Javascript

Asked

Viewed 1,939 times

8

I’m trying to make an algorithm that consists of:

Take a number, for example 46.5.

Go through this value and divide the entire part of the floating, ie, the whole part will stay in one variable, and the floating in another.

Using the example above would look:

partInteira = 46
partFluante = 5

I want to use this algorithm for a rounding function in Google Sheets.

Below is an algorithm made in Python, to facilitate the understanding of the idea:

def arredondar(numero):
    digitos = str(numero)

    partInteira = ""
    partFlutuante = 0
    tamanho = len(digitos)

    for i in range(tamanho):
        if digitos[i] == ".":
           partInteira = int(partInteira)
           partFlutuante = int(digitos[i+1])

           if partFlutuante > 5:
              return partInteira + 1
           elif partFlutuante < 5:
              return partInteira - 1
           else:
              return numero

        else:
           if i == (tamanho-1):
              return numero
           partInteira += digitos[i]
  • 1

    What have you ever tried to do?

3 answers

9


You can transform the number into a string and separate the whole part of the decimal part using the split, a string method in Javascript.

Something like that:

const num = 46.5;

// Convertemos o número para string:
const str = num.toString();

// Separamos nas duas partes.
const splitted = str.split('.');

// Parte inteira:
const int = parseInt(splitted[0]);

// Parte decimal ('0' por padrão).
const decimal = parseInt(splitted[1] || 0);

console.log(int, decimal);

You can even greatly reduce the code with map and allocation by unstructuring:

const num = 46.5;

const [int = 0, decimal = 0] = num.toString()
  .split('.')
  .map((num) => parseInt(num));
  
console.log(int, decimal);

You can even extract this behavior to a function by returning a array of two elements or an object. To learn more, see this other answer.

Something like that:

function splitNumber(num) {
  const [int = 0, decimal = 0] = num.toString()
    .split('.')
    .map((num) => parseInt(num));
    
  return [int, decimal];
}

// Imagine que esse `arg` vem como parâmetro:
const arg = 46.5;

const [int, decimal] = splitNumber(arg);
console.log(int, decimal);


It is worth remembering that, although the question, through its example, gives to understand that the intention is to separate the digits from the decimal separator of the number ., if the intention is, in fact, to separate the whole of the fractional part of the number, the another answer is mathematically more appropriate.

Thus, for the example of the question, 46.5, there may be two behaviors:

  • Divide into 46 and 5, two integers (appropriate as the example of the question).
  • Divide into 46 and 0.5, the whole and the fractional part (appropriate according to mathematical semantics).

And it is important, still, to be aware of the problems linked to scientific notation that can be returned by Number.prototype.toString, which may impair the approach to answers without a more appropriate approach (which probably does not fall within the scope of the question). This problem is, however, only noticeable in very large or very small numbers.

  • Thank you very much for the answer, there is only a small problem rs, as I want to use this algorithm within a rounding function, the number used in the example, would be taken as parameter of the function: example ** rounding(45.6)**

  • So, as I mentioned at the end of the answer, you can extract the behavior to another function and pass the number you have (get anywhere) as an argument. See the last example I just added. :-)

  • Aaaa, right. Could you show me an example of how to do this? rs I couldn’t quite understand the other link you highlighted

  • I just edited the answer, see the last example added.

  • I got it =D, thank you!!

  • I tried to extract the behavior, but the following error appears: |Typeerror: It is not possible to call the "toString" method Undefined.| This happens when I try to get the value that is coming as parameter

  • Try to give a console.log to see what this value is. By the error message, it is probably undefined or null, then the problem lies with the origin of the value...

Show 2 more comments

3

I just wanted to add a few details on the definition of the problem and the solutions of the other answers. It’s not that they’re wrong, but there’s a few you pay attention to.

First, if the numbers are, for example, 1.5, 1.05 and 1.00005: for these three cases, it is said that the decimal part is 5. Behold:

function splitNumber(num) {
  const [int = 0, decimal = 0] = num.toString()
    .split('.')
    .map((num) => parseInt(num));
    
  return [int, decimal];
}

console.log(splitNumber(1.5)); // [1, 5]
console.log(splitNumber(1.05)); // [1, 5]
console.log(splitNumber(1.00005)); // [1, 5]

But actually the decimal part of the second and third numbers is not exactly 5. In a is 0.05 and the other is 0.00005 - these zeroes make all the difference, because it’s not the same value.

So here comes the other one that I mentioned, which is the definition of the problem: it makes no sense to turn the decimal part into an integer, because for integers the left zero makes no difference, but for decimal places it does. Therefore, I suggest you do not make this transformation, and keep the decimal part as it is, without converting to integer. So you don’t lose the decimals.


Another problem is that turning the number into a string will not always work as expected:

function splitNumber(num) {
  const [int = 0, decimal = 0] = num.toString()
    .split('.')
    .map((num) => parseInt(num));
    
  return [int, decimal];
}

console.log(splitNumber(0.0000005)); // [5, 0]
console.log(splitNumber(10000000000000000000000)); // [1, 0]
console.log(splitNumber(10000000000000000000000.99299284982)); // [1, 0]

This is because from a certain value "very large" (or "very small"), the method toString returns the number represented in scientific notation. In the case of 0.0000005, for example, the result of toString is 5e-7. And how the function does the split of this string using the point as separator, the result turns out not to be the expected (related question).

One way to avoid this problem (and also the first, of not preserving all zeros of the decimal places) is simply to truncate the number to get the whole part, and then subtract this whole part from the original number (so what remains is the decimal part):

function splitNumber(num) {
  const int = Math.trunc(num);
  return [int, num - int];
}

console.log(splitNumber(1.5));
console.log(splitNumber(1.05));
console.log(splitNumber(1.00005));
console.log(splitNumber(0.0000005));
console.log(splitNumber(10000000000000000000000));
console.log(splitNumber(10000000000000000000000.99299284982));

But of course we now generate other "problems". In the second number above, the decimal part is 0.05, but the result turned out to be 0.050000000000000044. This happens because of how floating point numbers work. There is a more detailed explanation here, and in this answer has several other links that you can follow to delve into the subject. But at least we don’t remove the zeroes from the decimals, which in my opinion is an improvement.

And in the last number, the resulting decimal part was zero, as the decimal places were ignored because thereof. That is, even using math instead of conversion to strings, we will still be limited to the language’s implementation features (and there’s no way around that much - unless you use dedicated libraries to handle values as large as that one).

It is worth remembering that the solution with toString is also subject to this behavior, since it is something intrinsic to the way floating point numbers work:

function splitNumber(num) {
  const [int = 0, decimal = 0] = num.toString()
    .split('.')
    .map((num) => parseInt(num));
    
  return [int, decimal];
}

var x = 1.05 - 1; // supondo que o número é resultado de algum cálculo
console.log(splitNumber(x)); // [0, 50000000000000050]

If you want to avoid this, then you would have to deal with the numbers before (or after), either by rounding up, eliminating decimal places, etc (but then I believe you already escape the scope of the question).

3

To solve this problem just convert your number to string using the method toString:

var numero = 45.5;
var numero_str = numero.toString();

Do this, use the function split(), that will return an array:

var numero_split = numero_str.split(".");

// Apenas rodando para verificar no console
console.log(numero_split[0])

Browser other questions tagged

You are not signed in. Login or sign up in order to post.