12 ms·
Maybe it's a weird takeaway, but this line is really clever: var suit = i / 13 | 0; That's such a clean way to get a 0, 1, 2 or 3 from each card's `i` and I n
by riebschlager 11y ago
Maybe it's a weird takeaway, but this line is really clever:
var suit = i / 13 | 0;
That's such a clean way to get a 0, 1, 2 or 3 from each card's `i` and I never would have thought of it.
- pakastin 11y agoI think "value | 0" is basically same as "Math.floor(value)"
- ZitchDog 11y agoYes, but it is 18% faster do run the bitwise or on my machine: https://jsperf.com/or-vs-floor/2 https://jsperf.com/or-vs-floor/2
- ldesegur 11y agoi/13|undefined works too
- logicallee 11y agoplus i/13|undefined has that "this was originally written in javascript, not ported halfheartedly from some other language" feel. (Well, maybe PHP.)
- ygra 11y agoThat's just adding another conversion from undefined to Number to Int32 for the right operand. You could probably use false as well. Or the empty string.
- Stormcaller 11y agoIts because they don't do the same thing Math.floor() favors the number equal to/less than the parameter, Math.floor(-15.5) is -16 while (-15.5 | 0) is -15 Also because the returned value is int32[0], Math.floor(2147483648.5) is 2147483648 while (2147483648.5 | 0) is -2147483648 You are fine if you know the input is less than (2^31) + 1 and you want to truncate, rather than floor. [0]: http://www.ecma-international.org/ecma-262/6.0/#sec-binary-bitwise-operators-runtime-semantics-evaluation http://www.ecma-international.org/ecma-262/6.0/#sec-binary-b...
- nkron 11y agoECMAScript 2016 adds Math.trunc()[0] which should give the same value as | 0 for inputs that fit in 32 bits. [0] http://www.javascripture.com/Math#trunc http://www.javascripture.com/Math#trunc
- 4Data 11y agoHmm, pretty sure floor rounds a number downward to its nearest integer. So Math.floor(-15.5) would be 15. https://developer.mozilla.org/pt-PT/docs/Web/JavaScript/Reference/Global_Objects/Math/floor https://developer.mozilla.org/pt-PT/docs/Web/JavaScript/Refe...
- catchmrbharath 11y agoNope. Math.floor(-15.5) would be -16. It rounds a number downwards. -16 < -15.
- Stormcaller 11y agoLiterally the first example on that page: > Math.floor( 45.95); // 45 > Math.floor(-45.95); // -46 Its not like its hidden or anything... Its in the center of the page on my 1920x1080 screen.
- jpollock 11y agoThere is no substantial difference in performance on mine (within 2%), although the OR was always a little bit faster. Chrome 45 on Linux It's odd that a bitwise operator should have the effect of truncating the float (since X|0 == X)? I'm guessing there's an implicit type conversion to int in the middle?
- TazeTSchnitzel 11y agoThe bitwise operators don't make sense for floating-point values. So they work by converting to a 32-bit integer first.
- deleted 11y ago[deleted]
- aaronm67 11y agoAnd every time a developer sees that, they're going to google "bar javascript" "single bar javascript" "bitwise or javascript" "bitwise or javascript effect" until they figure out WTF is going on. This all to save a fraction of a microsecond on an operation that's called 60 times on the page.
- pkstn 11y agoActually only 52 :D But yeah, I agree about googling part: I remember having Googled "tilde javascript" and "pipe javascript".. :) Tilde is useful with indexOf: if (~array.indexOf(item)) {} ..equals to: if (array.indexOf(item) > -1) {}
- yellowapple 11y agoThis is the sort of thing that makes Perl readable in comparison to Javascript :)
- irascible 11y agogulp I guess I should stop using parseInt :/
- robocat 11y agovalue | 0 will always return a 32 bit integer. Math.floor(value) can return some weirder values such as: NaN (for anything that isn't a number), and Infinity, -Infinity, -0. And Math.floor(-1e-300); is -1 so care needs to be taken with floating values near zero.
- hacker_9 11y agoIn asmjs you see this sort of syntax 'num | 0' a lot [0] to enforce that the number is an int, so that may be where he got the idea. [0] http://www.sitepoint.com/understanding-asm-js/ http://www.sitepoint.com/understanding-asm-js/
- Stormcaller 11y agoIt exists in other languages, too, like PHP.
- TazeTSchnitzel 11y agoYou can do this in PHP, but you shouldn't. Use (int), like C.
- Stormcaller 11y agoIt is not much worse than using it in javascript. People do this in js because it saves a few keystrokes and its faster, not that it matters. Its a small thing. Its dirtier, for sure. I just tested it in PHP and it seems it is 20% faster in PHP compared to casting to int. Maybe someone out there will have a weird use case for that, or someone doesn't want to put more effort into writing code into terminal and doesn't care about his code being unreadable. I think its useful to know it exists. Btw, do you or someone else know why its faster in php too? Its a bitwise operation and I assume under the hood its casting to int, its weird to have it faster than casting it to int, why does this happen? It makes sense in javascript to that its faster than functions, but why it is faster than a cast in PHP?
- TazeTSchnitzel 11y ago> It is not much worse than using it in javascript. It is worse because people are even less familiar with this in PHP. It's not idiomatic. > I just tested it in PHP and it seems it is 20% faster in PHP compared to casting to int. How rigorous was your testing? Which version of PHP were you using? > It makes sense in javascript to that its faster than functions, but why it is faster than a cast in PHP? It shouldn't be. It might save an allocation in older PHP versions, I'm not sure.
- daok 11y ago1.89% faster than Math.Floor, 100% more hard to read.
- adamc 11y agoI used http://jsperf.com/or-vs-floor/2 http://jsperf.com/or-vs-floor/2 in Firefox 40.0.3 and it was only 0.37% faster. Was similar in Chrome.
- takeda 11y agoIf you're referring to |0 then I would disagree. It shows how horrible JavaScript is. This is very confusing if you're not familiar with this trick or strange behavior of the language. suit = int(i / 13) suit = (int)(i / 13) suit = math.floor(i / 13) Are much easier to understand for someone not familiar with the code.
- TazeTSchnitzel 11y agoThe behaviour of JavaScript's bitwise operators isn't that unreasonable, but the excessive use of this trick for tiny performance gains at the expense of readability is a shame.
- riebschlager 11y agoI take your point, but that's some crazy non-JS typecasting in your first two examples :)
- adamkochanowicz 11y agosuit = Integer(i / 13) suit = Math.floor(i / 13)
- fenomas 11y agoLanguages are what they are, and if you're going to use one you might as well use it idiomatically. Maybe it's just me, but I see "|0" all the time in JS, not as some kind of crazy performance hack, but used idiomatically to mean "truncate". And on the flip side with JS's lack of number types, any code that looks like it's doing type casts (rather than math) looks out of place. If one must mess around with JS number types then all you can really do is give hints to the optimizing compiler, in which case "|0" is the standard way to hint that you want a small int. Obviously what looks clean is a matter of opinion, but FWIW.
- DatBear 11y agoWhy not just i % 4?
- novaleaf 11y agothat would alternate the suit for each card, and all the aces would be the same suit, etc.
- deleted 11y ago[deleted]
- epyjao 11y agoIf you also take the cards modulo 13 for their face, this approach works. 4 and 13 are relatively prime, so each number between 1 and 52 can be uniquely represented by the function (x) -> (x%13, x%4).
- DatBear 11y agoYes, obviously it's not a drop in replacement as the behavior is different, but it does the same thing, giving you a number from 0 to 3 based on the card number. Pairing it with i%13 works just fine.
- redler 11y agoPutting aside whether this sort of thing is clever and clean or occult and confusing, another pattern of the same ilk is: ~~(i/13)
- tracker1 11y agofor me I see `~~` and I think coerce to integer value (the result will be an integer regardless of i's value, 0 if it fails a clean coercion) Similar to seeing `!!` and thinking true/false coercion.
- gcb0 11y agoon my deck hacks i use proper data structures but on the initializer for the deck i have `suit = i % 4`. which has the advantage of working with any size of deck. important since in brazillian truco you leave most of the numbers out ;)