Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #24783

Re: "i = i|0"

Message-ID <2773314.7tFKgFW6fd@PointedEars.de> (permalink)
From Thomas 'PointedEars' Lahn <PointedEars@web.de>
Organization PointedEars Software (PES)
Date 2014-06-12 20:25 +0200
Subject Re: "i = i|0"
Newsgroups comp.lang.javascript
References <emscripten-20140611221102@ram.dialup.fu-berlin.de> <5051886.MyCAqxjJIy@PointedEars.de> <lncpcv$rt0$1@news2.informatik.uni-stuttgart.de>

Show all headers | View raw


Thomas Richter wrote:

> Am 12.06.2014 00:20, schrieb Thomas 'PointedEars' Lahn:
>> First of all, this does _not_ express the C semantics in JavaScript, and
>> there is no other way.  “int” is a *generic* type in C/C++; IIUC, the
>> result could be a 32-bit integer when compiled for a 32-bit platform or a
>> 64-bit integer when compiled for a 64-bit platform.
> 
> Not quite. int is a type whatever the compiler chooses it to be, let it
> be 32 bit, 64 bit or 36 bit, no matter what the platform is. I have seen
> platforms were int was a 16 bit type even tough the platform was 32 bit
> wide.

That is what I said.  A “could” statement is never exclusive.
 
> IOWs, the C to JavaScript compiler can surely implement a valid C model
> on top of JavaScript with 32 bit ints, the decision to have ints 32 bit
> wide is not invalidated by the platform having any other native register
> size.

If there were 32-bit ints in JavaScript.  However, we have ascertained by 
now that this syntax does not result in the corresponding operation with 
asm.js.
 
>> By contrast, using the binary bitwise OR operator, as with all ECMAScript
>> binary bitwise operators, *always* creates an IEEE-754 double-precision
>> *floating-point* value representing a *32-bit* integer value.  Also, not
>> only the result will be such a value, but also the operands are converted
>> to such values internally, before the operation is performed.
> 
> Within the limits of what JavaScript has to offer, this is the closest
> it can do to emulate the C type system when operating on signed
> datatypes; these are also first converted to int (here emulated as 32
> bit types), then the operation is performed. It can get very tricky to
> emulate the *unsigned* types, and I wonder what the C to JavaScript
> compiler would do about them.

No, it fails badly at implementing the C “int” type because its "integers" 
by contrast are _not_ generic but *always* 32-bit.  So there is considerable 
information loss involved in this conversion; a loss that would have turned 
out to be critical if this syntax would lead to the operation it suggests 
(but it does not; this is just a type marker for asm.js, which either 
extends or violates ECMAScript there).
 
>> Conversion to an integer value of the ECMAScript Number type (i.e., where
>> the fractional part of the mantissa is zero), which appears to be the
>> goal here, can be better achieved with the Math.floor() and Math.ceil()
>> functions, e.g.:
> 
> No, I don't think that this is the goal here, i.e. rounding to an
> integer number (avoiding the term "int" here intentionally). An "int"
> has undefined behavior if an operation overflows.

The behavior appears to me to be well-defined.

> Just rounding would create another integer number, but one that is outside
> of the bit range, possibly with even weirder side effects in the program.
> That's possibly not quite what was intended. In the end, it probably does
> not matter much because, as said, C leaves it undefined what happens on
> overflow of the signed types, and the implementation just picked the
> simplest possible choice to create a "round to zero".

Rounding is not the point, achieving a zero fractional part is.  That is 
what Math.floor() and Math.ceil() do, with positive and negative numbers, 
respectively, and without information loss up to the IEEE-754 doubles 
integer precision limits (−2⁵³ and 2⁵³).
 
>> Of course, this still does not remotely implement the C semantics.  One
>> aspect of it is that code where you pass a non-integer would not compile.
> 
> Not so. Instead, C would truncate the non-integer to the next integer
> (cut off the fractional part) and would use that as input. The following
> compiles fine:
> 
> int plusone(int x)
> {
>    return x+1;
> }
> 
> int main(int argc,char **argv)
> {
> 
>    return plusone(2.2);
> }

Indeed it compiles (with gcc), even without warnings (using -Wall).  C is 
even weirder than I thought.
 
> I'm not sure how JavaScript handles negative values when applied to the
> binary or operator, but I would suspect that it also performs a "round
> to zero", which is exactly what C does, thus a perfect match. That is
> possibly even intentional in JavaScript.

(*Which* JavaScript are you talking about?)

In all ECMAScript implementations I am aware of, “|0” does the same as the 
suggested Math.floor()/Math.ceil(), with the disadvantage that it breaks 
outside the 32-bit integer range.
 
>> Since ECMAScript uses dynamic type-checking, it is not possible to
>> prevent compilation.  But at the very least passing unsuitable values
>> should cause an exception to be thrown, so that it becomes unnecessary to
>> handle them, e.g.:
> 
> Certainly not, since C does not have exceptions either.

“Either”?  I am aware that C does not have exceptions.  However, I have 
assumed, wrongly, that such C code would not compile.  So in a language that 
uses dynamic type-checking, like ECMAScript implementations, throwing an 
exception would have come closest to that.

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

Back to comp.lang.javascript | Previous | NextPrevious in thread | Find similar | Unroll thread


Thread

Re: "i = i|0" Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-06-12 00:20 +0200
  Re: "i = i|0" raltbos@xs4all.nl (Richard Bos) - 2014-06-12 11:33 +0000
    Re: "i = i|0" Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-06-12 14:28 +0200
  Re: "i = i|0" Thomas Richter <thor@math.tu-berlin.de> - 2014-06-12 19:52 +0200
    Re: "i = i|0" Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-06-12 20:25 +0200

csiph-web