0

I have a COM object which has a method that returns an unsigned int64 (VT_UI8) value. We have an HTML page which contains some JavaScript which can load the COM object and make the call to that method, to retrieve the value as such:

var foo = MyCOMObject.GetInt64Value();

This value can easily be displayed to the user in a message dialog using:

alert(foo);

or displayed on the page by:

document.getElementById('displayToUser').innerHTML = foo;

However, we cannot use this value as a Number (e.g. if we try to multiply it by 2) without the page throwing "Number expected" errors. If we check "typeof(foo)" it returns "unknown".

I've found a workaround for this by doing the following:

document.getElementById('displayToUser').innerHTML = foo;
var bar = parseInt(document.getElementById('displayToUser').innerHTML);
alert(bar*2);

What I need to know is how to make that process more efficient. Specifically, is there a way to cast foo to a String explicitly, rather than having to set some document element's innerHTML to foo and then retrieve it from that. I wouldn't mind calling something like:

alert(parseInt((string)foo) * 2);

Even better would be if there is a way to directly convert the int64 to a Number, without going through the String conversion, but I hold out less hope for that.

1
  • 2
    All numbers are doubles in Javascript. Therefore you should be aware that you might loose some precision by converting your 64bit int to a double. Commented May 5, 2010 at 19:02

3 Answers 3

3

This:

alert(Number(String(foo)) * 2);

should do it (but see below), if your COM object implements toString (or valueOf with the "string" hint) correctly (and apparently it does, if your innerHTML trick works -- because when you assign foo to innerHTML, the same process of converting the COM object to a string occurs as with String(foo)).

From Section 15.5.1 of the 5th Edition ECMAScript spec:

When String is called as a function rather than as a constructor, it performs a type conversion.

And Section 15.7.1

When Number is called as a function rather than as a constructor, it performs a type conversion

It may be worth trying just Number(foo) * 2 to make sure, but I don't think it'll work (it seems like your COM object only handles conversion to String, not Number, which isn't surprising or unreasonable).


Edit If String(foo) is failing, try:

alert(Number("" + foo) * 2);

I'm very surprised that your innerHTML trick is working but String(foo) is throwing an error. Hopefully "" + foo will trigger the same implicit conversion as your innerHTML trick.


Edit Okay, this COM object is being very strange indeed. My next two salvos:

alert(("" + foo) * 2);

That uses all implicit conversions (adding an object to a string converts the object to a string; applying the * operator to a string converts it to a number).

Alternately, we can make the string->number conversion explicit but indirect:

alert(parseInt("" + foo) * 2);
Sign up to request clarification or add additional context in comments.

6 Comments

I tried that, unfortunately, calling "String(foo)" yields a "String expected" error.
@Matt: Try alert(Number("" + foo) * 2) instead. (I'm very surprised that String(foo) doesn't work, but if innerHTML = foo works, then "" + foo should work.) (Edited my answer to include this.)
Interesting, the result of that is, apparently, always 0, so that won't work either. Thanks though.
@Matt: Did you try alert(parseInt("" + foo) * 2)? Just in case? (Or, actually, alert(("" + foo) * 2) should work -- that's using all implicit conversions.) (Answer edited; maybe it should just be a list of options using strikeout for the ones that didn't work. :-) )
@TJ Unfortunately those didn't work either. They both result in "NaN". Thanks for all the help, though!
|
1

Eek. Well if none of the explicit conversions are working because of the strange behaviour of the host object, let's try the implicit ones:

var n= +(''+foo);

I'm assuming you don't mind that the target type Number doesn't cover the full range of values of an int64 (it's a double, so you only get 52 bits of mantissa).

1 Comment

That results in n being set to 0. I know Number won't give me the range I need, but it's better than having nothing (especially since I've never seen this particular method return a result that couldn't fit in 32 bits).
0

Matt, from the comments to other answers, I suspect you're running this code in some sort of loop. If so, make sure that you check the returned value for null before trying your conversions.

var foo = MyCOMObject.GetInt64Value(); 
if (foo == null) {
  foo = 0; // Or something else
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.