# thanks and bugs

 bananbl Dec 9, 2009 at 5:11 PM As i posted in "reviews": "Thank you dude for your library!I've made cool app based on it: http://zcn.ru/tmp/palc.exe A calculator similar to the one from the Dos Navigator - old and lovely file manager. Three number representations, no silly buttons and other unnecessary stuff. My sources: http://zcn.ru/tmp/palc.rar" Now about those bugs I discovered: 1. division breaks if one of operators is:  x such as 1>x>-1, i.e. we try to execute this using W3b.Sine.Sample: 1>0.1/1         Exception during evaluation         System.IndexOutOfRangeException - Index was outside the bounds of the ar ray.            at W3b.Sine.BigNumDec.ToString() in C:\work\w3b\W3b.Sine\BigNumDec.cs :line 276            at W3b.Sine.Program.EvaluateExpression(String expression) in C:\work\ w3b\W3b.Sine.Sample\Program.cs:line 186 I suppose this is caused by lines 551 and 552 in BigNumDec.cs. When the number is less than one, the first zero indicating integer part of the number increases digit count by one. i.e. shifting _exp to 0 causes dividend to become "01". Later that leading zero hurts all. I solved it by removing those zeroes from both divisor and dividend before shifting radix point: int ii = divisor.Length - 1;             while (divisor[ii] == 0)             {                 divisor._data.RemoveAt(ii);                 ii--;             }             ii = dividend.Length - 1;             while (dividend[ii] == 0)             {                 dividend._data.RemoveAt(ii);                 ii--;             } the second issue: "0.02/1" will give us "2" the problem is in "ToString" (BigNumDec.cs, line 260) radix point occurs to be shifted too far, so this is never occurs:              if( i + _exp + 1 == 0 ) { // if reached radix point (line 273, BigNumDec.cs)  In that condition I manually insert the dot and the zeroes. I.E. I added the following from line 268: if(_exp<-Length)             {                 sb.Append('.');                 for (int patch = 0; patch < (-_exp - Length); patch++) sb.Append('0');             }   So, those are two bugs I discovered, though maybe its' reasons are not quite what I think they are.   And there's one else little thing: expression handling fails if there's more than one dot between operators. Like, the expression "1..2" parsed as "2".   This is it. Well, I'd like to thank you again W3b for your library, and for expression handling especially. If you gonna upgrade it further, would u please add bitwise operations, XOR, AND, OR, NOT? ;) Sergey. W3bbo Coordinator Dec 9, 2009 at 11:27 PM Edited Dec 9, 2009 at 11:28 PM Hey there, Thanks for the feedback and proposed fixes, they'll help a lot (especially as it's been over a year and a half since I last took a proper look at the BigNumDec code, I'm ashamed to say I've forgotten how it all works now). I'll look into submitting some patches over the Christmas holiday. As for the operations you proposed at the bottom: the following boolean logical operations are already defined: `x AND y == x && yx OR y == x || yx XOR y == x ^^ y NOT x  = !x` These operations only work when both operands are either numeric 1 (true) or 0 (false). Behaviour is undefined when either operand is not a valid value. bananbl Dec 11, 2009 at 10:17 AM Dont you think it could be useful to turn those logical operations into full fledged bitwise? I've made conversion routines for that, decimal to hexademical and back, tested it a little, so let me help you with XOR: ``` protected override BigNum XOR(BigNum operand2) { BigNumDec a = this; BigNumDec b = (BigNumDec)operand2; if((a._exp<0)||(b._exp<0))throw new FormatException("XOR requires integer operands"); List ah=dec2hex(a._data); List bh = dec2hex(b._data); if (ah.Count > bh.Count) { for (int x = 0; x < bh.Count; x++) ah[x] ^= bh[x]; b._data = hex2dec(ah); } else { for (int x = 0; x < ah.Count; x++) bh[x] ^= ah[x]; b._data = hex2dec(bh); } return b; } /********************* dec2hex ***********************/ static List> bht2 = new List>(); static List dec2hex(List x) { int i; int di = x.Count; CalcDec2HexTableUpTo(di); List r = new List(); for (i = 0; i < di; i++) { for (int j = 0; j < (x[i]); j++) addhecks2(i, ref r); } List hb = new List(); for (i = 0; i < r.Count; i++) { hb.Add((byte)(r[i] >> 0)); hb.Add((byte)(r[i] >> 8)); hb.Add((byte)(r[i] >> 16)); hb.Add((byte)(r[i] >> 24)); } return hb; } static void CalcDec2HexTableUpTo(int y) { if (bht2.Count == 0) { List L = new List(); L.Add(1); bht2.Add(L); } int x = bht2.Count; for (; x < y + 1; x++) { List L = new List(); bht2.Add(L); bht2[x] = mult10(bht2[x - 1]); } } static void addhecks2(int n, ref List L) { int x; ulong res; uint c = 0; for (x = L.Count; x < bht2[n].Count; x++) L.Add(0); int len = L.Count; for (x = 0; x < len; x++) { if (bht2[n].Count > x) res = (ulong)L[x] + bht2[n][x] + c; else res = (ulong)L[x] + c; L[x] = (uint)res; c = (uint)(res >> 32); } if (c != 0) { L.Add(c); } } static List mult10(List src) { int x; List dst = new List(); for (x = 0; x < src.Count; x++) dst.Add(0); ulong res; uint carry = 0; for (x = 0; x < dst.Count; x++) { res = (ulong)src[x] * 10 + carry; dst[x] = (uint)res; carry = (uint)((ulong)(res) >> 32); } if (carry > 0) { dst.Add(carry); } return dst; } /********************* hex2dec ***********************/ static List hex2dec(List b) { List res = new List(); int len = b.Count; List pow2 = new List(); List resb = new List(); pow2.Add(1); int x; int num; for (x = 0; x < len; x++) { num = b[x] % 16; for (int y = 0; y < num; y++) { addbint(ref resb, ref pow2); } mult16(ref pow2); num = b[x] / 16; for (int y = 0; y < num; y++) { addbint(ref resb, ref pow2); } mult16(ref pow2); } for (x = 0; x < resb.Count; x++) { if (resb[resb.Count - x - 1] != 0) break; } len = resb.Count - x; for (x = 0; x < len; x++) res.Add((sbyte)resb[x]); return res; } static void mult16(ref List a) { int x; int res; int c = 0; for (x = 0; x < a.Count; x++) { res = a[x] * 4 + c; a[x] = (byte)(res % 10); c = res / 10; } if (c != 0) a.Add((byte)c); c = 0; for (x = 0; x < a.Count; x++) { res = a[x] *4 + c; a[x] = (byte)(res % 10); c = res / 10; } if (c != 0) a.Add((byte)c); } static void addbint(ref List b, ref List a) { int x; int res; int c = 0; for (x = b.Count;x < a.Count; x++) b.Add(0); for (x = 0; x < b.Count; x++) { if(a.Count>x) res = (a[x] + b[x] + c); else res = (b[x] + c); b[x] = (byte)(res % 10); c = res / 10; } if (c != 0) b.Add((byte)c); } ``` will that help? SailorDan Jan 8, 2012 at 4:32 AM The BigNumDec.Subtract method can return a result with multiple leading zeroes.  This breaks the comparison operators.   prec.ToString "0.00000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"    Base.ToString "12345678987654321"    Test.tostring "12345678987654321.00000000000000000000000000000000000000000000000000000000000000000023834098950110192137166820000000000000000000000000000000000000000000000000000000000115033015464703892842429343054761" Diff = BigNumDec.Subtract(Test, Base)   Diff.Tostring "00000000000000000.00000000000000000000000000000000000000000000000000000000000000000023834098950110192137166820000000000000000000000000000000000000000000000000000000000115033015464703892842429343054761"  Loop Until Diff < Prec   diff < Prec False    prec.ToString "0.00000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"    Base.ToString "12345678987654321" String   Test.tostring "12345678987654321.00000000000000000000000010848928695462042036189410913805651783624392026389405334100268432944848201988435033324843558274348874639541420511106110431684603325101054864001507475186926564"  Diff = BigNumDec.Subtract(Test, Base)   Diff.Tostring "0.0000000000000000000000001084892869546204203618941091380565178362439202638940533410026843294484820198843503332484355827434887463954142051110611043168460332510105486400150747518692656400" Loop Until Diff < Prec   diff < Prec True  CompareTo suffers from the same problem, but also seems to have issues of its own.