Friday, September 28, 2007

The ruby code for unearthing vista multiplication(display) bug

is this
counter=0;total=0;
1.step(65535,0.1){|x| total+=1; y=((65535/x).to_s).delete('.').split(//).last; if(y.to_i==5 or y.to_i==0); counter+=1; puts "#{65535/x},#{x}-#{65535/x*x}"; end


I love ruby :)

Actually this code spits out 72000 such numbers however the bug is present in around 12000 such numbers. Seems my pattern is only 1/6 true :)

I found 12000 recurrence of excel 2007 multiplication bug

1.016265520786650 64486.1

7.988663375388550 8203.5
7.989832120258950 8202.3
7.994608046453750 8197.4
7.994803103498750 8197.2
7.996656620257950 8195.3
7.997827705300150 8194.1
8.001245330012450 8190.6
8.001831501831500 8190.0
8.006621788371550 8185.1
9.396911429431750 6974.1
9.399067766224450 6972.5
9.401899460576150 6970.4
9.406892789986650 6966.7
9.410675052772150 6963.9
9.412026598112850 6962.9
9.415812991192650 6960.1
9.417436663840550 6958.9

15.278360609875500 4289.4
15.290123888850000 4286.1
15.329824561403500 4275.0
15.356766256590500 4267.5
15.384163947510500 4259.9
15.387414886123500 4259.0
15.401156232374500 4255.2
15.430892394631500 4247.0
15.498403689251500 4228.5
15.536616011948500 4218.1
15.539563227657500 4217.3
15.559486217621500 4211.9
15.563550869193500 4210.8
15.573536750552500 4208.1
15.595031292387500 4202.3
15.712059458163500 4171.0
15.712436164856500 4170.9
15.712812889613500 4170.8
15.713943172281500 4170.5
19.260837619397500 3402.5
19.275000000000000 3400.0
19.358126070774500 3385.4
19.392495709297500 3379.4
19.436206180675000 3371.8
19.510851766947500 3358.9
19.647139944837500 3335.6
24.679897567221500 2655.4
24.689195298372500 2654.4
24.800378429517500 2642.5
24.925832952989500 2629.2
25.097656250000000 2611.2
25.113044144696500 2609.6
25.117856732206500 2609.1
25.174784880147500 2603.2
25.213527239150500 2599.2
25.322642967542500 2588.0
25.364786933467500 2583.7
25.520853615795000 2567.9
25.536764992401500 2566.3
25.572638233113500 2562.7
25.577628600421500 2562.2
25.645691476872500 2555.4
25.708065275380500 2549.2
25.718153991052500 2548.2
25.722191694795500 2547.8
25.872483221476500 2533.0
26.144977260033500 2506.6
26.182580902916500 2503.0
26.287605294825500 2493.0
26.294988564779500 2492.3
26.353144603506500 2486.8
26.417946547345500 2480.7
26.447798539085500 2477.9
26.480927751737500 2474.8
26.549586776859500 2468.4
26.561423418311500 2467.3
42.533099688473500 1540.8
42.602223233439500 1538.3
42.643805309734500 1536.8
42.780207585351500 1531.9
42.850137308748500 1529.4
42.970952724411500 1525.1
43.004790340573500 1523.9
46.330858960763500 1414.5
46.380042462845000 1413.0
46.485317066250500 1409.8
46.495211067754500 1409.5
46.657411362665500 1404.6
46.690652607580500 1403.6
46.720610251657500 1402.7
47.035814253929500 1393.3
47.137308494569500 1390.3
47.242647058823500 1387.2
47.300613496932500 1385.5
57.618252154035500 1137.4
57.750264363764500 1134.8
58.062372641091500 1128.7

78.929302661688500 830.3
79.072152509652500 828.8
79.253839642036500 826.9
79.292196007259500 826.5
79.426736153193500 825.1
79.571393880524500 823.6
79.648760330578500 822.8
79.794228661877500 821.3
79.823386114494500 821.0
80.018315018315000 819.0
80.194566813509500 817.2
80.273150416462500 816.4
80.430780559646500 814.8
80.450527866437500 814.6
80.549410029498500 813.6
80.658461538461500 812.5
80.967383246849500 809.4
81.067540821375500 808.4
81.137798687631500 807.7
99.870466321243500 656.2
100.390625000000000 652.8
104.073368270605000 629.7
104.272076372315000 628.5
105.074555074555000 623.7
105.923711006950000 618.7
106.250000000000000 616.8
107.030867221950000 612.3
109.480454393585000 598.6
123.047315058205000 532.6
126.588757967935000 517.7
138.230331153765000 474.1
139.140127388535000 471.0
142.250922509225000 460.7
142.995854243945000 458.3
143.089519650655000 458.0
148.135171790235000 442.4
153.298245614035000 427.5
153.874148861235000 425.9
154.308923946315000 424.7

157.120594581635000 417.1
158.144305019305000 414.4
160.546300832925000 408.2
160.901055732875000 407.3
162.496900570295000 403.3
164.826458752515000 397.6
171.692428608855000 381.7
177.169505271695000 369.9
198.771610555050000 329.7
200.596877869605000 326.7
200.781250000000000 326.4
207.520582647245000 315.8
208.179796696315000 314.8

269.802387813915000 242.9
287.812911725955000 227.7
298.157415832575000 219.8
305.382106244175000 214.6
312.220104811815000 209.9
312.816229116945000 209.5
315.223665223665000 207.9
315.679190751445000 207.6
317.053701015965000 206.7
318.131067961165000 206.0
321.092601665850000 204.1
331.654858299595000 197.6
334.532924961715000 195.9
337.287699433865000 194.3
342.219321148825000 191.5
345.648734177215000 189.6
351.771336553945000 186.3
381.017441860465000 172.0

695.700636942675000 94.2
706.196120689655000 92.8
715.447598253275000 91.6
720.164835164835000 91.0
726.552106430155000 90.2
753.275862068965000 87.0
766.491228070175000 85.5
772.818396226415000 84.8
773.730814639905000 84.7
782.974910394265000 83.7
788.628158844765000 83.1
798.233861144945000 82.1
800.183150183150000 81.9
803.125000000000000 81.6
850.000000000000000 77.1
915.293296089385000 71.6
947.037572254335000 69.2
951.161103047895000 68.9
992.954545454545000 66.0
1391.401273885350000 47.1
1430.895196506550000 45.8
1606.250000000000000 40.8
2332.206405693950000 28.1
2400.549450549450000 27.3
2436.245353159850000 26.9
3181.310679611650000 20.6
3212.500000000000000 20.4
3810.174418604650000 17.2
4174.203821656050000 15.7
5601.282051282050000 11.7
6425.000000000000000 10.2
7201.648351648350000 9.1
9929.545454545450000 6.6
12850.000000000000000 5.1

Excel 2007 bug

The now (in)famous excel 2007 multiplication bug is quiet interesting. First people thought it is a floating point bug but it seems it may not be the case. I did some analysis and found that the bug can be reproduced like this. Take two numbers who when multiplied give 65535(2^16-1). Suppose one of them is A and the other one is B such that A*B=65535. Now if A is a number such that A*10 is an integer and (B*10^N is and integer and B*10^N is of the form 5M (divisible by 5) (where M and N are interger) then this bug can be reproduced.
For instance 10.2(A) * 6425(B)

Monday, September 10, 2007

Choose the right tool

Everyday on Slashdot and elsewhere one comes across comments like PhP sucks, Ruby is slow, Rails doesn't scale, Perl is obfuscated, Java is slow etc. Most of these comments are posted by newbies(I being one of them) who don't have much idea about the "right tool" for a particular usage. So how do we choose the right tool ?
Well being an engineer I can tell you that this decision is should be based on optimal combinations of these factors(not in order of priority):
1. Load expected on the system
2. Amount of development time available
3. Quality of development resources available
4. Importance of the software being produced(critical/non critical)

5. Complexity

Expected load on the system: I think this one factor should play a major role in deciding the kind of tools to be used. If the expected no. of users on the system is in the order of 2000 requests/day, we can safely say that load is not much. However we must also keep in mind what is the distribution of this load. If there is a spike in the load at any given time of day/week/month/year which reaches, say , 200 req/sec for ten seconds and there is no load after that throughout the day, then the system must be capable of handling such loads. Therefore expected maximum load/sec multiplied by some safety factor (say 2) should be our design goal.
We must also consciously avoid premature optimization. Building a Google like system when we have a user base of 2000 is stupidity to say the least.

Amount of development time available(deadline): Some times it may be necessary to churn out some cool feature or application in short amount of time because it is sought after by the users. We cannot ignore that demand and sketch out an elaborate and mammoth design which would take months. It would be a better idea to code using some sort of "rapid prototyping tool" to gauge the user perception and then if it becomes popular then recode it into some other high performance language or "harden" the existing app by a code review.
Some amount of time should be kept aside for murphy 's sake

Quality of development resources available: This is one thing which should directly affect the tool being used. If we have a "super geek" team we can probably use any tool on earth. But sadly this is not the case most of the time and hence it is better to choose something which has a short learning curve and clear demarcations are available in the design to distribute it efficiently over a large non-high-quality team.

Importance of the software being produced: Well if we need an application which is not very critical or say some downtime would not hurt anything on the production side, then using a tool which makes life easy is a good idea. Also spending development time of a better quality resource is not that good an idea.

Complexity: Choice of tool should also depend on the complexity of the software that needs to be built. We cannot expect to build a complex application which say needs neural networks, backward chaining and symbolic calculations in php! Lisp would be a btter idea.

In my view before even we start designing a system we should create a list of the goals along with reasonable expected figures of key statistics. this would not only help us design the system better but also allow to take important desicions like no. of developers needs, technology to be used, amount of time expected for completion etc.

Gotchas!

Oracle:
If you have worked only with MySQL till now and planning to shift you apps in production on Oracle then you may run into a few very nasty gotchas.

1. "30 character" limit: I had a long (19 characters) table name (required due to rails convention) and some pretty long column names (due to legacy schema thingy). I wrote the find methods and bang! An error which said Oracle doesn't support identifiers longer than 30 characters! Whoa!!! I still don't understand what could be the logic behind a 30 character limit!

2. Oracle doesn't have a 'limit' keyword. Yes you read it correctly ! You cannot say something like this "select * from < table > limit 10, 100"! Oracle doesn't support this at all. You would need sub selects and stuff

3. Some of the table names which are allowed in mysql are not in Oracle like "date"...if I am not mistaken

Rails:
If you serialize a column and try to read the column if no data is there it returns a rather nasty error which says "ActiveRecord::SerializationTypeMismatch:"
http://dev.rubyonrails.org/changeset/6880