Category Archives: Number

Haskell Inspired zipWith() Function

Actionscript:
  1. initOperators();
  2.  
  3. trace(zipWith("-", [1,2,3], [1,2,3]));
  4. trace(zipWith("+", [1,2,3], [1,2,3]));
  5. trace(zipWith("*", [1,2,3], [1,2,3]));
  6. trace(zipWith("+", [1,1,1,3], [4,5,6,7]));
  7. trace(zipWith("<<", [2, 4], [1,1]));
  8. /*
  9. outputs:
  10.  
  11. 0,0,0
  12. 2,4,6
  13. 1,4,9
  14. 5,6,7,10
  15. 4,8
  16. */
  17.  
  18. function zipWith(op:String, a:Array, b:Array):Array{
  19.     var aLeng:int = a.length;
  20.     var bLeng:int = b.length;
  21.     var leng:Number = (aLeng <bLeng) ? aLeng : bLeng;
  22.     var zipped:Array = [];
  23.    
  24.     if (!this[op])return [];
  25.    
  26.     for (var i:int = 0; i<leng; i++){
  27.         zipped[i]=this[op](a[i], b[i]);
  28.     }
  29.     return zipped;
  30. }
  31.  
  32. function initOperators():void{
  33.     this["+"]=function(a:Number, b:Number):Number{ return a + b };
  34.     this["-"]=function(a:Number, b:Number):Number{ return a - b };
  35.     this["/"]=function(a:Number, b:Number):Number{ return a / b };
  36.     this["*"]=function(a:Number, b:Number):Number{ return a * b };
  37.     this["%"]=function(a:Number, b:Number):Number{ return a % b };
  38.    
  39.     this["&"]=function(a:Number, b:Number):Number{ return a & b };
  40.     this["<<"]=function(a:Number, b:Number):Number{ return a <<b };
  41.     this["|"]=function(a:Number, b:Number):Number{ return a | b };
  42.     this[">>"]=function(a:Number, b:Number):Number{ return a>> b };
  43.     this[">>>"]=function(a:Number, b:Number):Number{ return a>>> b };
  44.     this["^"]=function(a:Number, b:Number):Number{ return a ^ b };
  45. }

This snippet is basically like the haskell zipWith() function. It can combines two arrays into one array given a single function. In this case I defined a bunch of operator functions, but it would work with any kind of function that takes two arguments and returns a value. You could extend this to work with strings and do other strange things I guess.

If you have yet to go play with haskell ... go do it now.

Also posted in Operators, arrays, binary, functions, misc, return values | Tagged , , , | 2 Comments

Tausworthe Random Numbers (seeded)

Actionscript:
  1. // best thing about this are the random seeds
  2. var s1:Number= 0xFFFFFF;
  3. var s2:Number = 0xCCCCCC;
  4. var s3:Number= 0xFF00FF;
  5.  
  6. // saw this algorithm on this somewhat annoying thread:
  7. // http://www.reddit.com/r/programming/comments/7yjlc/why_you_should_never_use_rand_plus_alternative/
  8. // additional googling brought me to this: http://wakaba.c3.cx/soc/kareha.pl/1100499906/
  9. // and finally to this ( didn't understand most of this one) www.ams.org/mcom/1996-65-213/S0025-5718-96-00696-5/S0025-5718-96-00696-5.pdf
  10.  
  11. function rand():Number {
  12.     s1=((s1&4294967294)<<12)^(((s1<<13)^s1)>>19);
  13.     s2=((s2&4294967288)<<4)^(((s2<<2)^s2)>>25);
  14.     s3=((s3&4294967280)<<17)^(((s3<<3)^s3)>>11);
  15.     var r:Number = (s1^s2^s3) * 2.3283064365e-10;
  16.     r = (r<0) ? r+=1 : r;
  17.     return r;
  18. }
  19.  
  20. // see a visual comparison between this and actionscript's Math.random()
  21.  
  22. var canvas:BitmapData = new BitmapData(400,400,false, 0xCCCCCC);
  23. addChild(new Bitmap(canvas));
  24.  
  25. var posX:Number;
  26. var posY:Number;
  27.  
  28. addEventListener(Event.ENTER_FRAME, onLoop);
  29.  
  30. function onLoop(evt:Event):void {
  31.  
  32.     for (var i:int = 0; i<100; i++){
  33.         posX = rand() * 180
  34.         posY = rand() * 180
  35.         canvas.setPixel( 100 + posX, 10 + posY, 0x000000);
  36.     }
  37.    
  38.     for (i = 0; i<100; i++){
  39.         posX = Math.random() * 180
  40.         posY = Math.random() * 180
  41.         canvas.setPixel( 100 + posX, 210 + posY, 0x000000);
  42.     }
  43. }

The above snippet demo's an alternative random number generator that uses the Tausworthe method.


Top square is Tausworthe and bottom is Math.random()

I don't actually know much about this, or fully understand how it works. I just saw it on a random reddit thread, googled about it for a few minutes and then ported it to actionscript.

There's lots of talk about what the BEST random number generator is.... which one is the fastest, which one is the most random. etc... I don't really know much about that, especially since I'm just playing around with code and I don't need a RNG for some scientific experiment. For me, what's nice about this approach is the three random seeds. For some reason, Math.random() doesn't have a place where you can enter a seed for random numbers. Random seeds are very useful when you want to do something random but want to be able to replicate the random results at a later time. For instance:

Actionscript:
  1. var s1:Number= 0xFFFFFF;
  2. var s2:Number = 0xCCCCCC;
  3. var s3:Number= 0xFF00FF;
  4.  
  5. trace("first three values:");
  6. trace(rand());
  7. trace(rand())
  8. trace(rand())
  9.  
  10. s1 = 0xFF;
  11. s2 = 0xEFEFEF;
  12. s3 = 19008;
  13.  
  14. trace("\nfirst three values with different seeds:");
  15. trace(rand());
  16. trace(rand())
  17. trace(rand())
  18.  
  19. s1 = 0xFFFFFF;
  20. s2  = 0xCCCCCC;
  21. s3 = 0xFF00FF;
  22.  
  23. trace("\noriginal three values:");
  24. trace(rand());
  25. trace(rand())
  26. trace(rand())
  27.  
  28. function rand():Number {
  29.     s1=((s1&4294967294)<<12)^(((s1<<13)^s1)>>19);
  30.     s2=((s2&4294967288)<<4)^(((s2<<2)^s2)>>25);
  31.     s3=((s3&4294967280)<<17)^(((s3<<3)^s3)>>11);
  32.     var r:Number = (s1^s2^s3) * 2.3283064365e-10;
  33.     r = (r<0) ? r+=1 : r;
  34.     return r;
  35. }
  36.  
  37. /*
  38. outputs:
  39. first three values:
  40. 0.051455706589931385
  41. 0.050584114155822715
  42. 0.417276361484596
  43.  
  44. first three values with different seeds:
  45. 0.6032885762463134
  46. 0.9319786790304015
  47. 0.8631882804934321
  48.  
  49. original three values:
  50. 0.051455706589931385
  51. 0.050584114155822715
  52. 0.417276361484596
  53. */

I stumbled upon a bunch of other random number algorithms, maybe I'll throw them in a class in the next couple days.

Also posted in misc | Tagged , | 2 Comments

Adding Very Large Numbers

Actionscript:
  1. // tracing out large numbers will go into exponent notation
  2. trace(1000000000000000000000000);
  3. // outputs: 1e+24
  4.  
  5. var a:String =  "1000000000000000000000009";
  6. var b:String = "12000000000000000000000001";
  7.  
  8. // bigAdd function adds two large numbers
  9. trace(bigAdd(a, b));
  10. // outputs: 13000000000000000000000010
  11.  
  12. // unclear what regular addition is doing here:
  13. trace(int(a) + int(b));
  14. // outputs: -3758096384
  15.  
  16. function bigAdd(a:String, b:String):String{
  17.        var answer:String="";
  18.        var carry:int = 0;
  19.        var zeros:int = 0;
  20.        var i:int = 0;
  21.        var max:int = 0;
  22.        
  23.         // obtain max variable and prepend zeros to the shortest string
  24.        if (a.length> b.length){
  25.           max = a.length;
  26.           zeros = max - b.length;
  27.            for (i= 0; i<zeros; i++) {
  28.                 b = "0" + b;
  29.            }
  30.        }else if (b.length>  a.length){
  31.            max = b.length;
  32.            zeros = max - a.length;
  33.            for (i= 0; i<zeros; i++) {
  34.                 a = "0" + a  ;
  35.             }
  36.        }else{
  37.            // a and b have same number of digets
  38.            max = a.length;  
  39.        }
  40.        
  41.        // add each character starting with the last (max - 1),
  42.        // carry the 1 if the sum has a length of 2
  43.        for (i = max - 1;  i> -1; i--){
  44.                var sum:String = String(int(a.charAt(i)) + int(b.charAt(i)) + carry);
  45.  
  46.                if (sum.length == 2){
  47.                        answer = sum.charAt(1) + answer;
  48.                        carry = 1;
  49.                }else{
  50.                        carry = 0;
  51.                        answer = sum + answer;
  52.                }
  53.        }
  54.        if (carry == 1){
  55.            answer = 1 + answer;
  56.        }
  57.        return answer;
  58. }

This snippet demos a function called bigAdd(), which can be used to add very large numbers that the standard numerical datatypes (int, Number, etc) won't really work with. It uses a string based addition algorithm.

When I decided to write this snippet I dug around for awhile trying to find a nice elegant algorithm to port, something done without prepending zeros etc.... but I couldn't find one that suited my needs... so I just created this one from scratch. There's room for optimization and improvement but it works well enough for just playing around.

BigDecimal & BigInteger

A few months back I needed to do some programming with very large numbers. I dug around for awhile and eventually found out that java has a built in BigInteger andBigDecimal class.... I used java to write the program I had in mind, but thought it would be fun to eventually create something similar for ActionScript....

Also posted in misc, string manipulation, strings | Tagged , , , , | 2 Comments

10,000 35 ways, .toString(radix);

Actionscript:
  1. for(var i:int = 2; i<37; i++){
  2.     trace((10000).toString(i));
  3. }
  4. /*
  5. outputs:
  6. 10011100010000
  7. 111201101
  8. 2130100
  9. 310000
  10. 114144
  11. 41104
  12. 23420
  13. 14641
  14. 10000
  15. 7571
  16. 5954
  17. 4723
  18. 3904
  19. 2e6a
  20. 2710
  21. 20a4
  22. 1cfa
  23. 18d6
  24. 1500
  25. 11e4
  26. kec
  27. iki
  28. h8g
  29. g00
  30. ekg
  31. dja
  32. cl4
  33. bpo
  34. b3a
  35. aci
  36. 9og
  37. 961
  38. 8m4
  39. 85p
  40. 7ps
  41. */

I had either totally forgotten about or never known about the Number, uint, int etc... .toString() radix argument. Brock mentioned it to me in conversation and I've been having fun with it ever since. It's especially nice for tracing out hex numbers:

Actionscript:
  1. var red:Number = 0xFF0000;
  2. trace("decimal:");
  3. trace(red);
  4. trace("hex:");
  5. trace(red.toString(16));

Also posted in strings | Tagged , , | Leave a comment