Javascript: clarification on adding decimals and hex numbers

JavaScript and client side scripting.

Moderator: General Moderators

User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Javascript: clarification on adding decimals and hex numbers

Post by raghavan20 »

Lets consider the line below

Code: Select all

H0 = (H0+a) & 0xffffffff;  // note 'addition modulo 2^32'
The inputs:
H0 = 0x67452301;
a = 1112808245;

Process:
H0 = H0 + a:17325841931112808245
H0 & 0xffffffff:-1449574858


My doubts:
1. first, the H0 is hex, a is dec i suppose. the H0 value is automatically converted to 1732584193 in dec.
how can automatic conversion take place without explicit typecasting??

2. H0 + a : The Javascript should have assumed this as arithmetic addition operator instead it assumed as concatenation operator and concatenated the two inputs....why??

3. H0 & 0xffffffff:-1449574858...how this value comes up???

I welcome any kind of help :)
Charles256
DevNet Resident
Posts: 1375
Joined: Fri Sep 16, 2005 9:06 pm

Post by Charles256 »

it probably tied the two together because in original declaration you had an x..you can't add x to a number;) perhaps JS retains memory of that somehow ? :-/
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

  1. hex, decimal, and octal, like I said previously, are all native number formats. When parsed, they are immediately converted to their (in-memory) binary form.
  2. That's not normally possible. Are you sure a isn't a string? Javascript will generally do string work if any of the operands in an expression is a string unless implicit conversion can be performed.
  3. numbers are always signed in Javascript. The last bit of a 32 bit number is the sign bit. Since you are using the bitwise and operator with a full 32 bit numeric, a negative result would indicate that the most significant bit was set.
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

Thanks for your answers feyd
feyd wrote:hex, decimal, and octal, like I said previously, are all native number formats. When parsed, they are
immediately converted to their (in-memory) binary form.
Thanks for letting me know this native format concept which I am not aware of earlier
feyd wrote:That's not normally possible. Are you sure a isn't a string? Javascript will generally do string work if any of the operands in an expression is a string unless implicit conversion can be performed.
This is where 'a' comes from

Code: Select all

for (var t=0; t<80; t++) {
            var s = Math.floor(t/20); // seq for blocks of 'f' functions and 'K' constants
            T = (ROTL(a,5) + f(s,b,c,d) + e + K[s] + W[t]) & 0xffffffff;
            e = d;
            d = c;
            c = ROTL(b, 30);
            b = a;
            a = T;
        }

        // 4 - compute the new intermediate hash value
        H0 = (H0+a) & 0xffffffff;  // note 'addition modulo 2^32'
        H1 = (H1+b) & 0xffffffff; 
        H2 = (H2+c) & 0xffffffff; 
        H3 = (H3+d) & 0xffffffff; 
        H4 = (H4+e) & 0xffffffff;
feyd wrote:numbers are always signed in Javascript. The last bit of a 32 bit number is the sign bit. Since you are using the bitwise and operator with a full 32 bit numeric, a negative result would indicate that the most significant bit was set.
Can a negative integer be represented in hex?

4. I have tried to debug this stmt.

Code: Select all

H0 = (H0+a) & 0xffffffff;  // note 'addition modulo 2^32'

The inputs:
H0 = 0x67452301;
a = 1112808245;

Binary equivalents:
1111000001110001110000010111000010101010100010111111111100110101
11111111111111111111111111111111

Subjected to AND logical operation resulted:
10101010100010111111111100110101

Equivalent dec for the result :

2861301557 which is not equal to the result it gave (-1449574858)
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

your conversion logic from hex to binary seems very faulty

Code: Select all

[feyd@home]>php -r "$a=0x67452301;echo($a.chr(13).'0x'.dechex($a).chr(13).base_convert($a,10,2));"
1732584193
0x67452301
1100111010001010010001100000001

[feyd@home]>php -r "$a=1112808245;echo($a.chr(13).'0x'.dechex($a).chr(13).base_convert($a,10,2));"
1112808245
0x42541b35
1000010010101000001101100110101
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

1. I understand that you are trying to convert a in dec to hex and then a in hex to binary.

lets have a look at this again...

The inputs:
H0 = 0x67452301;
a = 1112808245;

Binary equivalents:
H0.a=(1111000001110001110000010111000010101010).(100010111111111100110101)
0xffffffff=11111111111111111111111111111111

Subjected to AND logical operation resulted:
(H0.a) & 0xffffffff = 10101010100010111111111100110101

Equivalent dec for the result :

2861301557 which is not equal to the result it gave (-1449574858)

2. Is it always necessary to prefix '0x' before any hex before its converted??? cos I never hv used 0x in all my computations.

for ex: if its 0xFFFFFF, I use ony FFFFFF. I think PHP does not mandate using 0x as prefix before hex numbers.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

raghavan20 wrote:Is it always necessary to prefix '0x' before any hex before its converted??? cos I never hv used 0x in all my computations.

for ex: if its 0xFFFFFF, I use ony FFFFFF. I think PHP does not mandate using 0x as prefix before hex numbers.
It's in the manual. 0x prefix for hex. "0" prefix for octal.

If I get time later I'll go over those calculations with some progressive outputs so it's clear what's happening but I'm sure javascript will be able to compute simple bitwise calculations without error ;)

http://www.php.net/manual/en/language.types.integer.php
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

how are you coming up with H0 = 1111000001110001110000010111000010101010 :?: It's 1100111010001010010001100000001
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

Thanks d11wtq for clarfiying the doubt.
sorry feyd, I dont know how I came up with that value for H0. your values for H0 and a are the right ones.
so lets say,

1.

Code: Select all

H0 = 1100111010001010010001100000001
a = 1000010010101000001101100110101

H0.a = 11001110100010100100011000000011000010010101000001101100110101
(H0.a) & 0xffffffff = 
(11001110100010100100011000000011000010010101000001101100110101) & (11111111111111111111111111111111)
= 11000010010101000001101100110101 = 3260291893
Still I dont know why I dont get the value that was returned in the script :cry:

2. H0 = (H0+a) & 0xffffffff; // note 'addition modulo 2^32'
I dont understand the note given above. can you explain me what actually they mean by modulo???
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

the operation is + not .

Code: Select all

1100111010001010010001100000001  H0
+  1000010010101000001101100110101  a
----------------------------------
  10101001100110010011111000110110  H0 + a
&  1111111111111111111111111111111  0xFFFFFFFF
----------------------------------
   0101001100110010011111000110110  697908790 (0x29993E36)
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

eventhought the pseudocode says H0 = H0 + a
here is what it actually returns when traced

Code: Select all

// set initial hash value [5.3.1]
var H0 = 0x67452301;

Output:

a, b, c, d, e, w[79]: 1112808245,1463342561,562251891,1746824694,-654444883,-2110912391
H0 + a:17325841931112808245
H0:-1449574858
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

it's been converted to a string during the operation or your output...
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

Its not my script feyd, its the implementation of the SHA-1 algorithm in Javascript.
It was done deliberately.

look at here to see the debugged values
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

as I said, the debug output is at fault:

Code: Select all

document.getElementById("display_messages").innerHTML += "<br />H0 + a:" + H0+a;
H0 is converted to a string and concatenated to the string, then a is converted to a string and concatenated.
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

yes, the debug statement was faulty.
the javascript assumed + to be concatenation operator rather as an arithmetic addition operator
but wrapping h0 +a with () = (h0 + a) made it properly work

Code: Select all

h0 = 1732584193
a = 1112808245
h0 + a  = 2845392438 = 10101001100110010011111000110110
(h0 + a) & 0xffffffff = is the same again = only bits which are set in h0+a are again set = 10101001100110010011111000110110 = which is right
There is one thing still I dont understand with the debug stmt
There are two conflicting values printed by H0 debug stmts.

Code: Select all

document.getElementById("display_messages").innerHTML += "<br />H0 + a:" + (H0+a);
H0 = (H0+a) & 0xffffffff;  // note 'addition modulo 2^32'
document.getElementById("display_messages").innerHTML += "<br />H0:" + H0;//gives -1449574858
//few steps later; i print it again
document.getElementById("display_messages").innerHTML += "<br />H0:" + H0.toHexStr();//gives 2845392438 in dec
Post Reply