Category Archives: Rant

Advice for new Aspirants

If you think that the sky is the limit you should refrain from working for NASA.

Anonymous government employee.

Advertisements

Firefox: Get Rid of the Scratchpad Greeting

The Firefox browser has a little tool for JavaScript editing build-in called “scratchpad”. Based on the editor CodeMirror it is a bit better than writing a small HTML file with a textarea and a button to eval() the content but not very much.

The pros are the ability to “fold” code and a some pop-up things like code completion.
The cons are many, the main theme is probably that bugs (including usability issues) get ignored but featuritis is rampant. Another one is the fact that you cannot configure it a lot, actually, only half a dozen things of which only one or two affect everyday work. Continue reading

JavaScript: When a Number is not a Number

And it hit me again: JavaScripts loose typing that isn’t very loose when you think it is.

I wrote some functions, for example

Number.prototype.f = function(){
  var k = this;
   ...
  if(k.isInt())
    ...
};

The function isInt is the polyfill for ECMAScript 6 Number.isInteger as a Number prototype. Inside this prototype is a check for NaN and finiteness. It’s a very simple thing:

Number.prototype.isOk = function(){
  return ( !isNaN(this) && Number.isFinite(this) )?true:false;
};

Number.isFinite is a build-in to Firefox now and it is also the culprit here, it returns false even if it gets a good, finite number. There’s also a polyfill over at developers.mmozilla.org, so with a little name changing, I was able to find the problems.
The polyfill:

// Number.isFinite polyfill
// http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite
if (typeof Number.isFinite2 !== 'function') {
    Number.isFinite2 = function isFinite2(value) {
        // 1. If Type(number) is not Number, return false.
        if (typeof value !== 'number' ){
            return false;
        }
        // 2. If number is NaN, +∞, or βˆ’βˆž, return false.
        if ( value !== value || value === Infinity || value === -Infinity) {
            return false;
        }
        // 3. Otherwise, return true.
        return true;
    };
}

The summary to the function Number.isFinite at MDN states

In comparison to the global isFinite function, this method doesn’t forcibly convert the parameter to a number. This means only values of the type number, that are also finite, return true.

That’s what I wanted, no isFinite("123") returning true, good!

At least that’s what I thought.

You might have guessed it already: the “Number is an Object and not a Literal” train hit me again πŸ˜‰

But that’s why I wrote xtypeof. Here in its basic version:

function xtypeof(obj){
  var tmp = typeof obj;
  if( tmp !== "object"){
    return tmp;
  }
  else{
    var toString = Object.prototype.toString;
    tmp = toString.call(obj);
    if(tmp !== "[object Object]"){
      return tmp.slice(8, -1).toLowerCase();
    }
    return "object";
  }
}

So changing to that and all is well and peaceful again?

Nope, of course not. I found out, after some fiddling, that the clever way to test for NaN value !=== value isn’t so clever at all. After exchanging it with the global isNaN() it works as expected. Expected by me, that is πŸ˜‰

Number.isFinite2 = function(value) {
  // 1. If Type(number) is not Number, return false.
  if (xtypeof(value) !== 'number' ){
    return false;
  }
  // 2. If number is NaN, +∞, or βˆ’βˆž, return false.
  if ( isNaN(value) || value === Infinity || value === -Infinity) {
    return false;
  }
  // 3. Otherwise, return true.
  return true;
};

There is also a problem with the global isNaN() (not really a problem, I think) but that get’s caught by the xtypeof check.

A standard conforming check for IEEE-754 NaN would be the following:

// Shamelessly stolen from the SunPro code
/*
 * ====================================================
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
 *
 * Developed at SunPro, a Sun Microsystems, Inc. business.
 * Permission to use, copy, modify, and distribute this
 * software is freely granted, provided that this notice
 * is preserved.
 * ====================================================
 */
function isnan(x){
  var hx,lx;
  var double_int = new DataView(new ArrayBuffer(8));
  // needs nevertheless a check if it is really a number
  double_int.setFloat64(0, x);
  hx = double_int.getInt32(0);
  lx = double_int.getInt32(4);
  hx &= 0x7fffffff;
  hx |= (lx|(-lx))>>>31;
  hx = 0x7ff00000 - hx;
  return (hx>>>31)|0;
}
Number.prototype.foo = function(){
  var a = this;
  return isnan(a);
};

You don’t need a check if you use it this way, because a Number is always a number πŸ˜‰
Test:

(Number.NaN).foo()        /* 1 */
(123).foo()               /* 0 */
("123").foo()             /* throws exception: "123".foo is not a function */
Math.sqrt(-1).foo()       /* 1 */ /* IEEE 754 7.2g */
(0/0).foo()               /* 1 */ /* IEEE 754 7.2e */
(Infinity/Infinity).foo() /* 1 */ /* IEEE 754 7.2e */
(1/0).foo()               /* 0 */ /* IEEE 754 7.3  */

Yes, the last one is correct, too. Division by zero returns Infinity with the sign set as if it is an ordinary, finite rational (e.g.: if q/r -Infinity) as ruled by IEEE-754 and ECMAScript says to be in concordance to the standard.

If you watch the blogosphere you will see a lot of rants about ECMAScript’s isNaN but the single problem is the automatic conversion such that isNaN("123") returns false. That is a known problem of the principal design of JavaScript from the early days on and it is hard to get rid off now but with the to-come Number.isNaN you’ll get at least a work-around.

JavaScript: passing by value or by reference?

Probably of no interest at all but who cares? I certainly don’t πŸ˜‰

In my already regretted start to write a bigint library in JavaScript from scratch I’m porting some code from a C library (libtommath) which does a small amount of pointer juggling end reference pushing.

In the times of asm.js and tools like emscripten it could be a small command line … uhm … command but that results in a considerably large blob of nearly unreadable JavaScript code. Although a fast one.

Being fast is not that bad for a large-number library but readability wins almost always in my case.

Now I’m lost and forgot what I was to say…

Ah, the problem of pointers and passing of references and values in JavaScript. The latter is simple: Objects gets passed as references, Strings are immutable and the rest gets passed as values. Continue reading

Adventures of a Programmer: Parser Writing Peril XXXVII

Now that I had some time at hand, even though it is Sunday, I laid my hand on Tom Wu’s big integer library to smooth out the edges, test my implementations of Karatsuba and Toom-Cook algorithms and other bits and bobs. A bit boring but there is a need to do so and that is not only my own opinion. It just suffers from a lot of old-browser-legacy. That is a thing I know very well and hate even more than seeds in my raspberry jam.
The thing I wondered about was the line Bigint.ZERO.subTo(this,r) to negate a bigint. It does exactly what you think it does, it subtracts a number from zero. So it is easily replaced by just changing the sign, isn’t it? Nope, of course not. The variable bigint.s is just a shortcut, you wouldn’t need it, the respective digits are negative, too. Try it out:

var a = nbv(-923);
console.log(a[0]);
console.log(a.negate()[0])

will result in 268434533 (0xffffc65) and 923 (0x39b) respectively. Padding to the left with ones and bit-negating the first result gives ~0xfffffc65 = 922.

I will not go to the length and explain the reason for this, just say that this made some things simpler algorithmically but a lot of it is also caused by the (mis)behaviour of old browsers. A hint: if you look at the start of his file you’ll find the name “Netscape” at one point. The younger ones of you might even need to ask Google what it was.
The last version had been published in February 2008 but the last version that was used in large numbers was probably 4.76 published in October 2000. My old SparcStation runs an older version of OpenBSD and I installed Netscape 4.76 as the browser πŸ˜‰

So, at the end of this song I will have to bite the bullet, grab Tom St Denis’ paper and rewrite it from scratch.

Great.

An I thought I could do the whole thing in two or three month.

Silly me! πŸ˜‰