-2

I hope I am explaining this correctly and apologize for any misunderstandings.

I would like to change some 2 decimal places numbers as below:

18.40 should become-> 18.40
18.41 should become-> 18.41
18.42 should become-> 18.42
18.43 should become-> 18.43
18.44 should become-> 18.44
18.45 should become-> 18.5
18.46 should become-> 18.5
18.46 should become-> 18.5
18.46 should become-> 18.5
18.46 should become-> 18.5

Basically i want to change the numbers based on the last digit in the number. If the last digit ( 2nd digit in 2 decimal places number) is 5 or greater than the first digit in 2 decimal place number should change to next incremental number.

For example 18.46 . 6 is greater than 5 so the 4 before the 6 should become 5. So the number will be 18.5

I hope this is clear now.

Thanks. Basically

Chris
  • 57
  • 7
  • 1
    Why does `18.42` not round down to 1dp, but `18.48` **does** round up...? The examples given seem inconsistent – Rory McCrossan Oct 13 '22 at 18:12
  • 18.42 rounds up to 18.4 according to the code i written, but i want it to round up to 18.42 instead – Chris Oct 13 '22 at 18:16
  • @Chris But why, in the list of 4 sample inputs/outputs you provide, do some round to one decimal place and some to two? Why do you indicate that 18.42 should round to 18.42, while 18.45 should round to 18.5? There is no obvious reason or clear requirement we can distill from this seemingly conflicting ask. – user229044 Oct 13 '22 at 18:18
  • It's also not clear why you would multiply by 20, and divide by 20. Multiplying by *100*, truncating, and then dividing by 100 is a way to convert to two decimal places *without* rounding, but multiplying by 20 makes no obvious sense here. If your input is `1.23`, then multiplying by 20 produces `24.6`. You round off the `6` so the whole thing becomes `25`, and then you divide by 20, producing `1.25`. So, of course this produces wrong results for any normal definition of "rounding". For your `18.46` example, you multiple to produce `369.20`, round to `369`, then divide back to `18.45`. – user229044 Oct 13 '22 at 18:22
  • @user229044 i added explanation. Do you please provide the code how this should be handled by multiplying by 100 and then dividing by 100? I tried total_gross_weight = Math.round(total_gross_weight *100) / 100; but it still gives me 18.48 for 18.48 – Chris Oct 13 '22 at 18:28
  • Your update really doesn't make things any clearer. Is there some external standard you're trying to implement that explains this? You don't "round off to the next digit" on a 5 and go from .45 to .6 in any definition of "rounding" I've ever heard of. And you typically don't round up when the least significant digit is > 5, and *do nothing* when it's <5. That means you're losing precision on half your inputs for seemingly no reason. Typically you want uniform output, where all numbers are accurate to the same degree, ie to two decimal places. – user229044 Oct 13 '22 at 18:33
  • 1
    you could use s/t like this: `convert = v => (v * 100).toFixed(0) % 10 < 5 ? v : v.toFixed(1),` – Nina Scholz Oct 13 '22 at 18:55
  • Do you understand that this makes no real sense, and is not how actual rounding works? You're going to wind up with `14.36` rounding to `"14.4"`, but `14.40` staying `"14.40"`. So your output will contain some instances of 14.40 and some instances of 14.4, which will actually be *different numbers*. – user229044 Oct 13 '22 at 19:34
  • @user229044 you might be reading too much into purpose. This question looks hypothetical where they might tweak for their usecase but are interested in methods to round the decimals. This could be used where significant digit is extensive (manufacturing accuracy) or to improve binning for statistics/charts. – vol7ron Oct 14 '22 at 04:56
  • @Chris any reason you expect `18.40` and not `18.4`? – vol7ron Oct 14 '22 at 04:58

3 Answers3

1

You can strip off the decimal portion, round that, then add that back to the integer portion:

const values = [18.40, 18.42, 18.45, 18.48]
const formatted = values.map(roundIt)
                             
function roundIt(v){
  let int = v|0
  let dec = v - int
  dec = Math.round( Number.parseFloat(dec).toFixed(2) * 10 ) / 10
  return Number.parseFloat(dec < .5 ? v : int+dec).toFixed(2)
}

console.log(formatted)
Mike
  • 94
  • 4
1

You could convert it by looking to the last digit.

const
    convert = v => (v * 100).toFixed(0) % 10 < 5 ? v : v.toFixed(1),
    data = [[18.40, 18.40], [18.42, 18.42], [18.45, 18.5], [18.48, 18.5]];

data.map(([v, w]) => console.log(v, convert(v), w));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • The desired output for `18.40` in all versions of OP's question has been `"18.40"`, with the trailing `0` retained. – user229044 Oct 13 '22 at 19:32
-3

You can use a built-in toFixed method of Number class for this case.

flosisa
  • 189
  • 7