0

So I'm working on dividing the width of a display and this results in not so clean numbers.

My current solution is to drop the right side and use it as padding for generating the tiles.

So for example, if I get the number 336.75 (1366 monitor minus scroll bar divided by 4)

I split it using the split method after having converted the number to a string.

The problem is I can't get the right side to have a decimal again.

Using:

var testNumber = 336.75,
    numString  = testNumber.toString(),
    numParts   = numString.split('.'),
    numLeft    = numParts[0],
    numRight   = numParts[1];

If I try to bridge the right side back to a decimal like this:

var newNum = parseInt('.'+numRight);

I get a NaN result.

I want to get that 0.75 number and use it as padding.

Right now it's as if .75 is the number 75 due to the lack of a missing decimal point.

parseFloat seems to work

  • Possible duplicate of [Get decimal portion of a number with JavaScript](http://stackoverflow.com/questions/4512306/get-decimal-portion-of-a-number-with-javascript) – Heather Sawatsky Dec 12 '16 at 22:12
  • For future reference, `parseInt` takes a `string` and reads/saves the digits until a non-number character is found. Therefore `parseInt("." + num)` would try to read the string `".75"`, would see the `'.'` character and terminate, returning `NaN`. `parseFloat` works because it is expecting that the string may have a `'.'` in it. – Heather Sawatsky Dec 12 '16 at 22:19
  • You could also use type casting: `Number('.'+numRight);` – BenM Dec 12 '16 at 22:30
  • Thanks for the responses. I realize it could be a possible duplicate, I was also wondering what is the best way to do this, but if I should remove the question or hide it/whatever I'll do that. – Jacob David C. Cunningham Dec 12 '16 at 22:52

2 Answers2

2

Well, what you've tried does actually work if you use parseFloat() (see this jsFiddle), but there's a much better and more efficient way to achieve what you're trying to do.

You can get the padding value quite easily by rounding down testNumber, and subtracting it from itself. You can use Math.floor() to do most of the heavy lifting for you:

var testNumber = 336.75,
    padding    = testNumber - Math.floor(testNumber); // padding == 0.75

Obtaining the modulus of the number is also a possibility, but it may be less readable:

var testNumber = 336.75,
    padding    = testNumber % 1; // padding == 0.75
BenM
  • 52,573
  • 26
  • 113
  • 168
  • Thanks. I was curious about using the floor/ceiling but was concerned of losing values due to rounding. I was trying to get as close as possible to keeping pixels without shaving them off of the tiles and use the rest as padding. It still doesn't seem to be a great solution as I have to turn on overflow-x: hide to not have the horizontal-scroll show up. – Jacob David C. Cunningham Dec 12 '16 at 22:53
  • It could be that you're not using `box-sizing` correctly, but without seeing more of your code, it's very difficult to assess. – BenM Dec 12 '16 at 22:55
  • What do you mean by "correctly" ? I did add "box-sizing" border-box to the top of my code in the body tag, but also I did implement a CSS-reset file. – Jacob David C. Cunningham Dec 12 '16 at 22:56
  • That's alright, I appreciate the offer to help. I will have to look into that though, already there's another value for box-sizing "content-box" – Jacob David C. Cunningham Dec 12 '16 at 23:01
2

Even more simple:

var testNumber = 336.75;
var padding = testNumber % 1; // 0.75

Edit:
As per discussions in the comments, an interesting (and annoying) problem is seeing simple floating point math resulting in long results to 12 digits. For example, take 2.3 and we want to get the 0.3 from it.
2.3 % 1 = 0.299999999998 .... What?!

The same thing happens with the other answer's solution:
2.3 - Math.floor(2.3) = 0.29999999998 .... :(

It seems to have to do with how floating point values are physically stored. Take a look at this for more information: Is floating point math broken?


As a final solution, you could use toFixed(n):

(2.3 % 1).toFixed(4); // "0.3000"

Or as a number instead of a string:

parseFloat((2.3 % 1).toFixed(4)); // 0.3

Although you would lose a little precision on numbers that legitimately have more than 4 decimal places: 2.3456789 -> 2.3457

Community
  • 1
  • 1
Heather Sawatsky
  • 352
  • 3
  • 14
  • I tried this before but it returned a result which had 12 places or so. Unless that was with 2 instead of 1. – Jacob David C. Cunningham Dec 12 '16 at 22:52
  • @JacobDavidCunningham I've just done some research into this... Turns out modulo should only be used for integers. Rounding errors are extremely common in languages that allow modulo to be used with floats, due to the way floats are stored in memory. See: http://stackoverflow.com/questions/588004/is-floating-point-math-broken for more info. However, Math.floor isn't any more reliable. I'll make an edit. – Heather Sawatsky Dec 12 '16 at 23:18
  • No problem. Thanks for letting me know. At this point I'm just going to use parseFloat. I appreciate your efforts. – Jacob David C. Cunningham Dec 12 '16 at 23:32
  • @JacobDavidCunningham To be clear, the `numString.split('.')` isn't perfect either. It assumes the number will always have a `'.'` as the delimiter, but that isn't true in Europe (where they use `','`). – Heather Sawatsky Dec 12 '16 at 23:39
  • I saw some threads about that. Even dealing with pixels? (any thing that needs separation it'll be using commas?) interesting... not sure if I should take it into consideration. – Jacob David C. Cunningham Dec 13 '16 at 01:32