3

I wrote a function that behaves differently depending on the numeric type of it's parameters. Integer or float.

Using some code from this question How do I check that a number is float or integer? it was easy to detect if float or not but then I stumbled upon the case that javascript casts 1.0 to 1 without cause if you call a function using that number.

Example:

function dump(a, b) {
 console.log(a, typeof b, b);
}

dump('1', 1);
dump('1.0', 1.0);
dump('1.1', 1.1);

Output chrome, firefox, ie, opera and safari all gave the same result:

1   number 1
1.0 number 1 "wrong"
1.1 number 1.1

I know that javascript only knows the type number but that forced cast seems to go way overboard. The only solution I came up with was to call the function using string values like '1.0', detect the dot and use parseFloat or parseInt.

Any suggestion on that?

Community
  • 1
  • 1
naden
  • 126
  • 8
  • Why do you need `1.0` as compared to `1`? They are the same value. JavaScript has no concept of `int` or `float`, just `number`. – gen_Eric Aug 03 '12 at 15:40
  • 1
    What is is function you wrote? Why does it matter if its an `int` or `float`? – gen_Eric Aug 03 '12 at 15:42
  • The function returns a random number e.g. between A and B. Depending on the initial value it can eighter bei 4,10 = > 7 (int) or 1.5, 12 => 4.25 - you get the point. – naden Aug 03 '12 at 15:54
  • I still don't understand. You just want the average of the numbers (wouldn't `1.5, 12` be `6.75`)? That "example" doesn't show why it matters if it's an `int` or a `float`. – gen_Eric Aug 03 '12 at 15:55
  • It can be any floating point number between 1.5 and 12 or whatever range you call the function with. – naden Aug 03 '12 at 15:58
  • Oh, if the parameters are ints you want to return an int, and if they are floats, return a float. I get it now. – gen_Eric Aug 03 '12 at 16:00
  • The only solution you have is to pass the parameters as strings (and check if they have `.`s). `1.0` is "converted" to `1`, and there is no way to detect that it started as `1.0`. P.S. You can use `parseFloat` on "ints" too. – gen_Eric Aug 03 '12 at 16:02
  • You're right, but thats not the point here. The function itself is part of something bigger and does not realy matter. Would be very handy if you had any suggestions regarding the initial problem description. But I guess there is no solution. – naden Aug 03 '12 at 16:04
  • `1.0` is interpreted as `1` and there is no way to detect that `1.0` was entered. So, the "solution" is to keep it as a string, and detect the `.`. – gen_Eric Aug 03 '12 at 16:06
  • Yes, as mentioned in my intial post, I already did that, but hoped for some guru hint. Anyway, proof is always good. – naden Aug 03 '12 at 16:11

2 Answers2

4

You've acknowledged that JavaScript only has a single Number type. As such, 1 is identical to 1.0.

If you need this for display purposes, then you should use toFixed.

1..toFixed(1); // "1.0"
  • It's not for display purpose. Depending on the result of the operation the function return an float or int value using parse(Type). – naden Aug 03 '12 at 15:51
  • @naden: You can use `parseFloat` on "ints" too. `parseFloat('12') === 12`. – gen_Eric Aug 03 '12 at 15:58
  • 1
    @naden: I don't understand. You've already stated that you're aware that there is no such distinction in JavaScript. If you want JavaScript to behave as though there's a distinction when there is none, then aside from using strings, I'm afraid you're out of luck. –  Aug 03 '12 at 16:04
  • 1
    ...JavaScript sees `1.0` and `1` as identical. JavaScript sees `"1.0"` and `"1"` as distinct. Those are your basic options. –  Aug 03 '12 at 16:06
  • I do, but javascript is the most surprising language I know, there is very often a hidden hack. – naden Aug 03 '12 at 16:09
  • 1
    @naden: Yes... surprising... `;)` Sadly, aside from using strings, or some other way to manually communicate this information, there's no real solution. Passing `1.0` will always be seen as having passed `1`. –  Aug 03 '12 at 16:16
  • Unfortunate but all browsers behave like that, so one have to accept. – naden Aug 03 '12 at 16:19
  • 1
    @naden: One option would be to use a custom number constructor that accepts the initial value as a string, stores that value, but gives its *toNumber* conversion for math operations. http://jsfiddle.net/rMWmr/ Not perfect, and certainly not as nice as using number literals, but maybe helpful? –  Aug 03 '12 at 16:37
  • Interesting idea, but way to complicated for this simple function. – naden Aug 03 '12 at 16:43
0
number%1===0 

If that condition is true , it's integer, else it's float

kidwon
  • 4,448
  • 5
  • 28
  • 45
  • Unfortunately for the case I pointed out you are wrong, because of the forced "cast". You may run the example code to see it prooven. – naden Aug 03 '12 at 15:50
  • I'm not wrong it's just the way js works. Anyway now you have to modify one out of 10 which is far better. http://jsfiddle.net/EKmT3/5/ – kidwon Aug 03 '12 at 16:02
  • To be exact, you are not always wrong but regarging my case ;) It depends on the function input. See http://jsfiddle.net/7mrqM/ – naden Aug 03 '12 at 16:08
  • I don't see anything different from my post. It's 1 of out 10 you have to deal with .0 numbers – kidwon Aug 03 '12 at 16:14
  • The difference is, that the parameter is 1.0 "float" and the function alerts "int". – naden Aug 03 '12 at 16:15
  • In C#, Java or any strong type language, maybe – kidwon Aug 03 '12 at 16:17