4

In my implementation I provide a function to JavaScript that accepts a parameter.

v8::Handle<v8::Value> TableGetValueIdForValue(const v8::Arguments& args) {
  v8::Isolate* isolate = v8::Isolate::GetCurrent();
  v8::HandleScope handle_scope(isolate);

  auto val = args[1];

  if (val->IsNumber()) {

    auto num = val->ToNumber();
    // How to check if Int or Double    

  } else { 
     // val == string 
  }
}

Now this parameter can have basically any type. As I support Int, Float and String I want to efficiently check for these types. Using IsNumber() and IsStringObject() I can make sure that the objects are numberish or a string.

But now I need to differentiate between an integer value and a float. What is the best way to perform this test? Is there a way to call / use the typeof function exposed to JS?

Morwenn
  • 21,684
  • 12
  • 93
  • 152
grundprinzip
  • 2,471
  • 1
  • 20
  • 34
  • search for "class Value" in http://izs.me/v8-docs/v8_8h_source.html. There are functions `bool Value::IsInt32` and `double Value::NumberValue` which could be interesting. – Andrew Tomazos Jun 12 '13 at 08:57

3 Answers3

5

Quick Answer

v8::Value::NumberValue() will will return the value of the javascript Number without loss of precision.

Explanation

It is true that the set of numbers representable by int64_t and double is different. And so is natural to be concerned about what happens if the value is actually int64_t because v8::Value defines both

V8EXPORT int64_t v8::Value::IntegerValue() const;
V8EXPORT double v8::Value::NumberValue() const;

What is a v8::Number?

Consider v8::Number doc

Detailed Description

A JavaScript number value (ECMA-262, 4.3.20)

IntegerValue does return an int64_t, but there will be no more precision available, because the value is stored internally as a double-precision 64-bit binary format IEEE 754 value.

Testing in a browser

Checking if javascript can represent a value that a double can't but an int64_t can.

2^63 - 1 is equal to 9223372036854775807

Try typing the following in a javascript console; this value is parsed but the extra precision is thrown away because double can't represent it.

>9223372036854775807

the result

9223372036854776000
Community
  • 1
  • 1
waTeim
  • 9,095
  • 2
  • 37
  • 40
  • `v8::Value::NumberValue() will will return the value of the javascript Number without loss of precision.` This helped me add to a double I had already defined, thank you – Jonathan Aug 11 '19 at 06:56
4

Try IsInt32 or IsUint32() to check the number is integer or not.

https://github.com/v8/v8/blob/master/include/v8.h#L1313

mattn
  • 7,571
  • 30
  • 54
  • Thanks, this is true, however there is a light problem here: If you look at the implementation of the method in https://github.com/v8/v8/blob/master/src/api.cc#L2641 you will see that it first checks for `IsSmi()` (small integer) and than further checks if the double representation can be converted forth and back to/from an integer to see if the value is stable. Thus a value like `3.0` would be treated as an integer, even though it's a `Number`. Any comments on that? – grundprinzip Jun 19 '13 at 10:55
  • As far as JavaScript semantics is concerned, 3.0 *is* an integer. Whether V8 internally represents it as a float or not is an implementation detail, which is why the predicate is implemented as it is. – Andreas Rossberg Jul 17 '13 at 17:26
  • I'm having a problem here. I am passing 47 as an argument, but IsInt32 is returning false. Anyone got any ideas? – Jesse Pepper Jan 21 '15 at 13:46
  • @JessePepper IsUint32 also return false? – mattn Jan 21 '15 at 16:22
  • `if(!args[1]->IsInt32()) { cerr << "not int32"; } auto keyId = args[1]->Int32Value(); ` keyId has a sensible value, like 47 even though the error "not int32" is printed out. – Jesse Pepper Jan 23 '15 at 05:41
  • 1
    What value did you pass into the function. `foo(42)` ? or `foo("42")` ? – mattn Jan 23 '15 at 06:42
0

Try using this line;

bool isInt = ( num->NumberValue() ) % 1 == 0;

NumberValue returns a double with the number's value, and the % 1 == 0 will return true if the value returned is evenly divisible by 1.