...

View Full Version : toString()



clear
08-01-2011, 03:11 AM
I'm average when it comes to math so I'm having trouble understanding the concept of how you convert an integer to a string, and what would be the best outcome? Can someone help me understand the toString() method please?

jmrker
08-01-2011, 04:18 AM
Not much to it. See results of script below and look at comments.


<script type="text/javascript">
var n1 = 3; // a number
var n2 = 4; // another number

var s1 = n1.toString(); // a string
var s2 = n2.toString(); // another string

var nadd = n1+n2; // add numbers
var nsub = n1-n2; // subtract numbers
var nmul = n1*n2; // multiply numbers
var ndiv = n1/n2; // divide numbers

var s = s1+s2; // add (concatenate) strings
// cannot subtract, multiply or divide any two strings
// string would need to be converted to numbers before math can be done
// stings to numbers by Number(), parseInt(), parseFloat(); stringNumber * 1;

alert(nadd+'\n'+nsub+'\n'+nmul+'\n'+ndiv+'\n'+s);
</script>

Old Pedant
08-01-2011, 04:34 AM
Are you talking about how to *IMPLEMENT* toString()???

If so, are you talking about JavaSCRIPT or Java?? Because this sounds more like an exercise for a class in Java than for one in JavaSCRIPT. (This forum is for JavaSCRIPT. Almost the only similarity to Java is the first 4 letters of their names.)

If you are indeed asking how to implement toString()--that is, write your own as if the method didn't already exist--then do let us know. And confirm whether you are talking JavaScript or not.

clear
08-01-2011, 04:38 AM
Ah, no this is completely for JavaScript. I'm just 'thrown off I guess you could say' by changing a number into a word, if that's how toString() works. Or do I have the understanding wrong?

What I mean by that is say my small script is

var one = 1;
var changed = one.toString();

alert(changed);

what will changed return and why??

So, from jmrker's example above, what I get out of it is it just changes the datatype itself and not the value, which is why the concatanation was possible and it didnt use math when using the + operator, at least thast what I got out of his code example. Is that what it is? so since you passed the two 'number' variables into the toString() method, we can now execute methods and treat these variables as if they are now datatype strings? Is it that simple? I'm probably just overthinking this.

Old Pedant
08-01-2011, 05:00 AM
Well, yes and no.

Changing the datatype isn't at all as simple as you might think.

The internal representation of, say, the number 101 might be something like

00000000 00000000 00000000 001100101

That's a 4-byte integer. Or it might be stored as


01000001 10010100 00000000 00000000

that's a 4-byte floating point number (if I got my bits in the right spots...it's been at least a dozen years since I played with floating point at the bit level).

But that number *AS A STRING* would be


00110001 00110000 00110001

Which is actually THREE SEPARATE ASCII CHARACTERS. The character "1", the character "0", and then the character "1". (And, actually, each character is likely 2 bytes long, not one as shown, because JS is a Unicode language...but let's not get into that.)

The point is, as a *string*, there is nothing to distinguish "101" from "aba" or "$?X" or any other three ASCII characters. Excepting, of course, that actual values of the characters.

So you wouldn't try to do

"Axe" * "Woof"
(in an attempt to multiply two strings).

And if JavaScript weren't such a forgiving language (a.k.a. an "untyped" language), then you wouldn't be able to do

"101" * "371"

As it happens, JMrker didn't tell the whole truth: If you attempt to do that with JavaScript, it *WILL* work and you *WILL* end up multiplying two numbers, just as if you had coded

101 * 371

That's because JavaScript (almost, but not quite, alone among common langusges--see also PHP) *will* coerce a string into a number if it thinks that doing so will allow it to perform a mathematical operation.

BUT...that is not the case with

"101" + "371"
where the result will be

"101371"
and that's because of an idiocy perpetrated in the design of Java many moons ago (and copied by JavaScript) wherein they decided to use the + operator for both mathematical addition and string concatenation. So if used with strings, you get concatenation. (PHP isn't my favorite language, but they got it right: PHP uses a period for string concatenation. Personally, I would have rather seen an operator that is otherwise unused, such as @ or # or $, but oh well...)

jmrker
08-01-2011, 03:08 PM
As it happens, JMrker didn't tell the whole truth: If you attempt to do that with JavaScript, it *WILL* work and you *WILL* end up multiplying two numbers, just as if you had coded
Code:

101 * 371

That's because JavaScript (almost, but not quite, alone among common langusges--see also PHP) *will* coerce a string into a number if it thinks that doing so will allow it to perform a mathematical operation.

BUT...that is not the case with
Code:

"101" + "371"

where the result will be
Code:

"101371"


The reason I did not "tell the whole truth" is because I find it easier to remember the rules
rather than the rules AND then the exceptions to the rules. :rolleyes:

For example, while
var n = '101' * "371'
might work very nicely for some math calculations,
if the user has entered the '101' as '1O1' instead,
then when they get an error on the 'O'
because it looks similar to the '0'
they would not need to remember the exceptions. :D

rnd me
08-01-2011, 09:49 PM
you can use + to coerce a number:


"101" + "371" == "101371";


+"101" + +"371" == 472

Old Pedant
08-01-2011, 11:55 PM
Oh, I 100% agree with you, JMrker! I *NEVER* rely upon JavaScript converting strings to numbers for me.

I *always* do something like:


var n = Number( someString );
if ( isNaN(n) ) { alert("doofus...I want a number"); }
...

(Or parseInt if I want to insist that the value be an integer. Or ... )

I think it is a real hack to code stuff like


var n = 1 * someString;

I know it works. I just don't like it.

rnd me
08-02-2011, 04:50 AM
1* is messy, but Number() is several times slower...

i like operational casters:

var n = +someString;

var n = +new Date;


var b = !!someString;

strings are slightly more complicated:

var s = ""+someString;

var s = ""+new Date;



try to avoid the performance overhead of calling type functions (String, Number, Boolean), especially in loops and animation code.

bullant
08-02-2011, 06:53 AM
try to avoid the performance overhead of calling type functions (String, Number, Boolean), especially in loops and animation code.

I use the Number object all the time to convert a string to a number without any noticeable increase in execution time or any other overhead.

Whenever someone says something is faster or slower, I usually ask them to quantify how much faster or slower because if the order of magnitude is in nano or even micro-seconds I couldn't care less about the increase in execution time.

Philip M
08-02-2011, 07:26 AM
I use the Number object all the time to convert a string to a number without any noticeable increase in execution time or any other overhead.

Whenever someone says something is faster or slower, I usually ask them to quantify how much faster or slower because if the order of magnitude is in nano or even micro-seconds I couldn't care less about the increase in execution time.

I have to say that I fully agree with these remarks. But I do not really understand why Old Pedant objects to the efficient var n = 1 * someString;

bullant
08-02-2011, 12:59 PM
he didn't say he objects to it. He said he doesn't like it.

I don't like it either. It looks klunky and is a "poor man's" way of doing it imo.

Philip M
08-02-2011, 02:24 PM
As you so often say, you are entitled to your opinion. :)

Why is var n = 1 * someString;
somehow less acceptable than
var n = +someString;

bullant
08-02-2011, 02:28 PM
As you so often say, you are entitled to your opinion. :)


yep, and I posted why I agree with Old Pedant ;)



Why is var n = 1 * someString;
somehow less acceptable than
var n = +someString;

less acceptable to who?

jmrker
08-02-2011, 02:56 PM
Just an observation ... ;)
I'm not sure the operational casters idea by 'rnd me' are beneficial to me:


<script type="text/javascript">
var s1 = '123';
var s2 = '456';
var n1 = +s1;
var n2 = +s2;
n = n1 + n2;
sa = +s1 + +s2;
ss = +s1 - +s2;
sm = +s1 * +s2;
sd = +s1 / +s2;

alert(n+'\n\n'+sa+'\n'+ss+'\n'+sm+'\n'+sd);
alert('Still concatenates: '+ +'123'+ +s1+'\nbut with () works OK: '+ (+'123'+ +s1));
</script>

While the operations do work to cast the string to a number,
IMO, all the extra '+' characters in a row looks confusing to the casual coder.

For example, with a slip of the space bar and the expression
var n = +s1 + +s2;
becomes:
var n = +s1++s2;

Rowsdower!
08-02-2011, 03:07 PM
As you so often say, you are entitled to your opinion. :)
yep, and I posted why I agree with Old Pedant ;)



Why is var n = 1 * someString;
somehow less acceptable than
var n = +someString;

less acceptable to who?

Soooooo... How long have you two been married?

And don't you have a private room (http://www.codingforums.com/showthread.php?t=230283) for this type of behavior? :D

rnd me
08-02-2011, 04:55 PM
let's back away from sweeping generalizations here.

i don't wan't to be thought to have claimed that "you should always use +string" or something; that's silly.

like many things in programming, its a typical tradeoff; you can either optimize for humans or machines.


i agree that Number is easier for noobs to read, maybe for even non-noobs too.
parseInt is the slowest of them all; one should at least use the mnemonically-correct Number or Math.floor if you want to use a function call.

in general, JavaScript performance doesn't matter, and for simple data-drive sites and apps,
a few ms here or there won't be hugely noticeable, even on slow phone browsers.
if you have something that doesn't have to be fast, and readability is beneficial, go with Number.

In an up-front situation where these casts are all done at load/ready time, it really doesn't matter much either.

if you are doing any type of animation, even slight performance improvements result in lowered chances of cpu_max_activity, smoother animations, and longer phone battery life, go for the fastest possible performance; are noobs really gonna re-tween your timing functions, or mess with low-level dnd code, or re-optimize your tight loops using duff's devices?

you can use both guys! use the one most appropos to your situation.

know what the options are, and consciously choose the optimial one; that's what good programmers do.
bad programmers latch on to a certain unshakable way of doing things, damn the torpedoes; ala "eval() is bad, i'll never use it"...

Old Pedant
08-02-2011, 08:14 PM
What he said.

(Referring to RndMe's post #17.)

If I was after performance, I would definitely try a couple of variations (if not more) to find which is fastest.

I just meant to say that I use Number() and parseInt() for their clarity of meaning. I don't do much in the world of animation; primarily I am concerned with forms and validation and range limiting. So performance in that kind of code is largely immaterial. Clarity of code--especially for the poor sap who has to come after me and clean up my junk--is more important.

There's no one-answer-fits-all. (And p.s.: In MSIE, at least up to version 5, *all* of the afore-mentioned code variations ended up going through one choke point--a call to the COM function variantChangeTypeEx--which is where the bulk of the time was spent. So any variations in performance were minor if an actual string-to-number conversion was required. I had access to the C++ source code for JScript version 5, but haven't seen it since then, so can't speak for more recent versions.)

bullant
08-02-2011, 11:30 PM
Soooooo... How long have you two been married?


Mrs bullant and I are coming up to our 32nd anniversary :)

bullant
08-02-2011, 11:36 PM
if you have something that doesn't have to be fast, and readability is beneficial, go with Number.


I have never noticed any "slowness" or increased execution time when using the Number object.

Can you post some example code where you believe Number is not fast and some example code where you quantify how much faster you think it is than using Number().

I suspect any difference in execution time will be microscopically tiny.

Old Pedant
08-03-2011, 02:30 AM
The other thing that occurred to me: Why would you ever need/want to use Number() or any other equivalent in any animation or other performance-critical situation? I'm having a hard time coming up with a good example.

I mean, I've seen code that does stuff like this:


...
var left = Number( document.getElementById("whatsit").style.left );
if ( left > xyz ) left -= 32;
else left += 9;
document.getElementById("whatsit").style.left = left + "px";
...

But I would hope that you wouldn't really do that in a performance criticial situation. You'd stash a reference to the object in some variable and ditto to the value of the style.left (as a number) so you'd only need to do:


...
if ( whatsitLeft > xyz ) whatsitLeft -= 32;
else whatsitLeft += 9;
whatsitRef.style.left = whatsitLeft + "px";
...

Or similar, of course. The idea being to avoid both the string-to-number parse and the lookup by id [which might be just as slow!] any place in your loop/critical code.

So now I really do have to wonder: Why would you ever need to worry about the performance of Number() or equivalent?

bullant
08-03-2011, 02:39 AM
I suspect the difference in execution time for those 2 code examples would be "sub atomic" in size and not worth worrying about.

Old Pedant
08-03-2011, 02:53 AM
<shrug>Really doesn't matter if it's "subatomic" or not. Just as a matter of good programming practice why would you choose to do lookups and conversions every time through a loop?

Anyway, I *have* coded things in the past (not in JS, but in Java and C++ and Pascal) where indeed doing lookups by id and/or string-to-number conversions would have been out of the question, making the code way too slow. But those involved real-time processes collecting or processing kilobytes to megabytes of data per second. Not something you would typically do in JavaScript.

For once, though, my disagreement is not with you, Bullant. I'm just trying to figure out why, indeed, anybody would think that there's a case where the performance of Number(), et al., *should* matter. Simply because, if it does, then the program should most likely be re-coded to avoid the issue.

bullant
08-03-2011, 03:05 AM
Just as a matter of good programming practice why would you choose to do lookups and conversions every time through a loop?


Obviously you wouldn't.

But if for some reason (through lack of knowledge, experience or whatever) someone writes code that might not be as "efficient" as someone else might write then unless the code is doing iterations in at least the thousands in total, then any increase in execution time will most likely be totally insignificant if noticeable at all.

In this case I am mainly referring to the Number() object that rnd me suggested is not fast but I disagree with, especially in the absence of any verifiable data showing it to be slow relative to another method.

So I gather that we are essentially in agreement on this one.

Old Pedant
08-03-2011, 03:42 AM
I know I'm going to regret this...



<script>
var s1 = new Date();
var t = 0;
for ( var i = 1; i <= 500000; ++i )
{
var n = Number("3.14159265");
t += n;
}
var s2 = new Date();
alert( "Time for Number: " + ( s2.getTime() - s1.getTime() ) + ", total " + t);
var s3 = new Date();
t = 0;
for ( var j = 1; j <= 500000; ++j )
{
var n = 1 * "3.14159265";
t += n;
}
var s4 = new Date();
alert( "Time for multiply: " + ( s4.getTime() - s3.getTime() ) + ", total " + t );
</script>

With Firefox, the Number() loop runs roughly 4.5 times faster than the multiply loop.

With MSIE 7, the Number() loop runs only about 1.5 times faster than the multiply loop, but definitely faster.

MSIE 7 is about 40% slower for Number() than FF.

*** NOW ***

With Chrome, the Number() loop is *FASTER* than the multiply loop!!! Only by 15% or so, but still faster!

Also, Chrome's fastest time--with Number()--is a tad slower than FF's fastest time--with multiply.

SO...

There isn't any universal answer!! (Though Chrome met my personal expectations closer than either FF or IE.)

**********

No, I didn't try the unary plus operator or any of the other variations. I was happy enough that the results from Number() vs. multiply were so inconsistent. <grin/>

bullant
08-03-2011, 03:51 AM
I know I'm going to regret this...


I like it :thumbsup: and I'm certainly not trying to have a go at you......

but (no offence)

as I have posted in this and other threads, when I see comments like below




MSIE 7 is about 40% slower for Number() than FF.

*** NOW ***

With Chrome, the Number() loop is *FASTER* than the multiply loop!!! Only by 15% or so, but still faster!

Also, Chrome's fastest time--with Number()--is a tad slower than FF's fastest time--with multiply.

SO...



where someone says something is faster, slower, better, worse or whatever than something else without actually quantifying it (a % is nothing more than a ratio and not an absolute quantity in itself), it means zero to me because X% of a few nano or even milli-seconds is still next to zero and not worth considering imo.

bullant
08-03-2011, 04:16 AM
What for me would be a more meaningful example is displaying the actual time difference between the 2 methods.

So, as per your example with 500,000 (1/2 a million iterations) the execution time difference between the 2 examples over only 6 runs in my IE range from 6 milliseconds to 41 milliseconds with the average around 18 milliseconds.

If you reduce the 500,000 iterations down to a more common, say, 50 iterations the outputed execution time diffrence returned 0 milliseconds after another 6 runs. But that is probably due to rounding.

So as I posted earlier, unless you are doing iterations in the thousands, whether you use Number() to convert a string to a number or another method, the difference in execution time is totally insignificant imo and so it doesn't matter which method you use.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>

<script type="text/javascript">
var s1 = new Date();
var t = 0;
for ( var i = 1; i <= 500000; ++i )
{
var n = Number("3.14159265");
t += n;
}
var s2 = new Date();
//alert( "Time for Number: " + ( s2.getTime() - s1.getTime() ) + ", total " + t);
var s3 = new Date();
t = 0;
for ( var j = 1; j <= 500000; ++j )
{
var n = 1 * "3.14159265";
t += n;
}
var s4 = new Date();
//alert( "Time for multiply: " + ( s4.getTime() - s3.getTime() ) + ", total " + t );

alert("Time difference between the 2 methods = "+(s2.getTime() - s1.getTime() - s4.getTime() + s3.getTime())+' milliseconds');
</script>


</head>
<body>

</body>
</html>

And if you really want to start splitting hairs (or atoms ;)), the execution time difference is really slightly less then what is alerted because "technically" we need to subtract the time (probably nano seconds) it takes javascript to create the Date object.

Old Pedant
08-03-2011, 05:05 AM
Can not disagree at all.

As I said, I knew I would regret posting that.

But my curiosity was finally piqued enough to make me see whether all the assertions about multiply and unary plus were true. And since it turns out that even *THOSE* assertions aren't true for all browsers, I find no justification for ever using code that doesn't clearly say what it is doing.

I think what is most surprising to me is that the results vary SO much between implementations of JavaScript. I know from personal experience (writing compilers) that you wouldn't find such big differences between (say) various C++ compilers. (Well, you would find vast differences between C++ in 1991 or so vs. C++ today, but assuming we are talking about contemporary implementsions you'd only find minor differences.) It says to me that the world of JS implementations is still in flux.

bullant
08-03-2011, 05:22 AM
yep, agree with what you say and in particular with :


....I find no justification for ever using code that doesn't clearly say what it is doing......


which is why I posted earlier that I always use Number() to convert strings to numbers.

Having said that, I have no issue with anyone using someString*1 and because it works I won't tell anyone to not use it, or similar methods, because as you have shown in your example there are no significant consequences normally, but imo using something like someString*1 looks klunky at best and so I won't use it.



As I said, I knew I would regret posting that.


not sure why :confused: . I'm glad you did. Something like that is what I was essentially asking rnd me to post to try to justify his sugestion to not use Number because he feels it is significantly slower. Your code shows clearly that it isn't.

Old Pedant
08-03-2011, 05:30 AM
> As I said, I knew I would regret posting that.

LOL! Only because I know it will open up another can of worms. Ah, well.

rnd me
08-03-2011, 09:53 AM
I know I'm going to regret this...


With Firefox, the Number() loop runs roughly 4.5 times faster than the multiply loop.

With MSIE 7, the Number() loop runs only about 1.5 times faster than the multiply loop, but definitely faster.

MSIE 7 is about 40% slower for Number() than FF.

*** NOW ***


With Chrome, the Number() loop is *FASTER* than the multiply loop!!! Only by 15% or so, but still faster!


i get different results:


chrome 14
Time for Number: 1823, total 1570796.324990203
Time for multiply: 1355, total 1570796.324990203
Time for plus: 1323, total 1570796.324990203


ff6
Time for Number: 247, total 1570796.324990203
Time for multiply: 82, total 1570796.324990203
Time for plus: 176, total 1570796.324990203


ie9
Time for Number: 353, total 1570796.324990203
Time for multiply: 270, total 1570796.324990203
Time for plus: 256, total 1570796.324990203



live test (http://danml.com/sandbox/#{"auto":true,"IN":"void(0);","CODE":"var r=[]; \nvar proceed=confirm(\"running benchmarks, please wait...\");\nif(!proceed){throw({message:\"benchmark cancelled by user\"});}\nvar s1 = new Date();\nvar t = 0;\n\nfor ( var i = 1; i <= 500000; ++i )\n{\n var n = Number(\"3.14159265\");\n t += n;\n}\nvar s2 = new Date();\nr.push( \"Time for Number: \" + ( s2.getTime() - s1.getTime() ) + \", total \" + t);\n\n\n\n\n\nvar s3 = new Date();\nt = 0;\nfor ( var j = 1; j <= 500000; ++j )\n{\n var n = 1 * \"3.14159265\";\n t += n;\n}\nvar s4 = new Date();\nr.push( \"Time for multiply: \" + ( s4.getTime() - s3.getTime() ) + \", total \" + t );\n\n\n\n\n\n\n\n\nvar s3 = new Date();\nt = 0;\nfor ( var j = 1; j <= 500000; ++j )\n{\n var n = +\"3.14159265\";\n t += n;\n}\nvar s4 = new Date();\nr.push( \"Time for plus: \" + ( s4.getTime() - s3.getTime() ) + \", total \" + t );\n\nr.join(\"\\n\")"})

-----------


Number is slower everywhere. i do expect the diff to wear away as more performance is squeezed out of js.
still, i can tell you anecdotally that processing backup csvs into a strong array of objects goes faster without Number or what i used at first: parseFloat...

if you are doing animation, server-side js, data processing, or writing low-level library functions, consider using the faster code: users matter more than devs.

just for kicks, folding helps too, and JSON.parse is faster than Number (http://danml.com/sandbox/#{"IN":"void(0);","CODE":"var r=[]; \nvar proceed=confirm(\"running benchmarks, please wait...\");\nif(!proceed){throw({message:\"benchmark cancelled by user\"});}\nvar s1 = new Date();\nvar t = 0;\n\nfor ( var i = 1; i <= 500000; ++i )\n{\n var n = Number(\"3.14159265\");\n t += n;\n}\nvar s2 = new Date();\nr.push( \"Time for Number: \" + ( s2.getTime() - s1.getTime() ) + \", total \" + t);\n\n\n\n\n\nvar s3 = new Date();\nt = 0;\nfor ( var j = 1; j <= 500000; ++j )\n{\n var n = 1 * \"3.14159265\";\n t += n;\n}\nvar s4 = new Date();\nr.push( \"Time for multiply: \" + ( s4.getTime() - s3.getTime() ) + \", total \" + t );\n\n\n\n\n\n\n\n\nvar s3 = new Date();\nt = 0;\nfor ( var j = 1; j <= 500000; ++j )\n{\n var n = +\"3.14159265\";\n t += n;\n}\nvar s4 = new Date();\nr.push( \"Time for plus: \" + ( s4.getTime() - s3.getTime() ) + \", total \" + t );\n\n\nvar s3 = new Date();\nt = 0;\nfor ( var j = 1; j <= 500000; ++j )\n{\n var n = JSON.parse(\"3.14159265\");\n t += n;\n}\nvar s4 = new Date();\nr.push( \"Time for json.parse: \" + ( s4.getTime() - s3.getTime() ) + \", total \" + t );\n\n\n\n\nvar s3 = new Date();\nt = 0;\nfor ( var j = 1; j <= 500000; j+=2 )\n{\n var n = +\"3.14159265\";\n t += n;\n n = +\"3.14159265\";\n t += n;\n}\nvar s4 = new Date();\nr.push( \"Time for plus (folded): \" + ( s4.getTime() - s3.getTime() ) + \", total \" + t );\n\n\nr.join(\"\\n\")"})

bullant
08-03-2011, 10:41 AM
if you are doing animation, server-side js, data processing, or writing low-level library functions, consider using the faster code: users matter more than devs.


Obviously its beneficial to write code that is efficient but as shown earlier, when the potential time saving is only a handful of milliseconds (thousandths of a second) how you code is nowhere near as critical as ensuring the code actually does what it's supposed to.

Basically, the end result being correct is much more important than how you do it.

It would be interesting to see the results you get with running the code in post 27.

I still haven't seen any code example where using Number() is any disadvantage.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum