public static bool IsZero(BCD bcd) { try { if (bcd is null) { return(true); } else if (bcd._rem is null) { return(false); } else { foreach (Once once in bcd.BCDbyteValue) { if (once.Val != 0) { return(false); } } } return(true); } catch (Exception ex) { throw new BCDException("IsZero error.", bcd, ex); } }
public static BCD Parse(string val) { try { if (!Regex.IsMatch(val, "[+-]?[0-9]+")) { throw new Exception("parse error."); } BCD ret = new BCD(); if (val.StartsWith("-")) { ret.SetSign(-1); for (int i = 1; val.Length > i; i++) { ret.BCDbyteValue.Add(new Once() { Val = (byte)(val[i] - '0') }); } ret.MaxLen = val.Length - 1; return(ret); } else if (val.StartsWith("+")) { ret.SetSign(0); for (int i = 1; val.Length > i; i++) { ret.BCDbyteValue.Add(new Once() { Val = (byte)(val[i] - '0') }); } ret.MaxLen = val.Length - 1; return(ret); } else { for (int i = 0; val.Length > i; i++) { ret.BCDbyteValue.Add(new Once() { Val = (byte)(val[i] - '0') }); } return(ret); } } catch (Exception ex) { throw new BCDException("Parse error.", null, ex); } }
public static BCD Abs(BCD bcd) { try { BCD ret = bcd.Clone(); ret.SetSign(0); return(ret); } catch (Exception ex) { throw new BCDException("Abs error.", bcd, ex); } }
public BCD Clone() { try { BCD a = new BCD(); a.SetSign(this.Sign); a.MaxLen = this.BCDbyteValue.Count; a.BCDbyteValue.AddRange(this.BCDbyteValue.ToArray()); return(a); } catch (Exception ex) { throw new BCDException("Clone error.", this, ex); } }
public static BCD Multiply10(BCD org, int digit) { try { BCD ans = org.Clone(); for (int i = 0; digit > i; i++) { ans.BCDbyteValue.Add(Once.Zero); } ans.MaxLen = ans.BCDbyteValue.Count; return(ans); } catch (Exception ex) { throw new BCDException("Multiply10 error.", org, ex); } }
public override bool Equals(object obj) { BCD a = obj as BCD; return(a != null && this == a); }
public static BCD operator /(BCD l, BCD r) { try { if (r == BCD.Zero) { throw new DivideByZeroException(); } if (l.Sign < 0) { if (r.Sign < 0) { BCD cl = Abs(l); BCD cr = Abs(r); BCD ans3 = cl / cr; ans3.Rem.SetSign(-1); return(ans3); } else { BCD cl = Abs(l); BCD cr = Abs(r); BCD ans = cl / cr; ans.SetSign(-1); ans.Rem.SetSign(-1); return(ans); } } else { if (r.Sign < 0) { BCD cl = Abs(l); BCD cr = Abs(r); BCD ans2 = cl / cr; ans2.SetSign(-1); ans2.Rem.SetSign(0); return(ans2); } if (l < r) { BCD ans1 = BCD.Zero; ans1.Rem = l.Clone(); return(ans1); } BCD tmp = r.Clone(); BCD ans = BCD.Zero; if (l == tmp) { return(BCD.One); } else { bool isEnd = false; BCD ll = l.Clone(); while (!isEnd) { int dec = 0; BCD tmp2 = r.Clone(); while (ll > tmp2) { tmp2.BCDbyteValue.Add(Once.Zero); dec++; } if (ll != tmp2) { tmp2.BCDbyteValue.LastOut(out Once dum); dec--; } tmpCount = 0; BCD a = BCD.Zero; while (ll > a) { a += tmp2; tmpCount++; } if (ll == a) { ans.BCDbyteValue.Add(new Once() { Val = (byte)tmpCount }); } else { a -= tmp2; tmpCount--; tmpCount = tmpCount < 0 ? 0 : tmpCount; ans.BCDbyteValue.Add(new Once() { Val = (byte)tmpCount }); } ll -= a; if (ll < r) { for (int i = 0; dec > i; i++) { ans.BCDbyteValue.Add(Once.Zero); } isEnd = true; ans.Rem = ll; } } return(ans); } } } catch (Exception ex) { throw new BCDException("operator / error.", l, r, ex); } }
public static BCD operator *(BCD l, BCD r) { try { int maxLen = Math.Max(l.Length, r.Length); l.BCDbyteValue.VirtualCount = maxLen; r.BCDbyteValue.VirtualCount = maxLen; if (l.Sign < 0) { if (r.Sign < 0) { return(Abs(l) * Abs(r)); } else { BCD a, b, c; b = Abs(l); c = Abs(r); a = b * c; a.SetSign(-1); return(a); } } else { if (r.Sign < 0) { BCD a, b, c; b = Abs(l); c = Abs(r); a = b * c; a.SetSign(-1); return(a); } else { if (IsZero(l) || IsZero(r)) { return(new BCD()); } BCD gre = l > r ? l : r; if (gre != l) { r = l; l = gre; } BCD ans = new BCD(); IEnumerator <Once> re = r.BCDbyteValue.GetReverseEnumerator(); int digit = 0; while (re.MoveNext()) { BCD m1 = new BCD { MaxLen = maxLen }; int carry = 0; int idx = maxLen - 1; Once m = re.Current; if (m.Val == Once.Zero.Val) { digit++; continue; } IEnumerator <Once> le = l.BCDbyteValue.GetReverseEnumerator(); while (le.MoveNext()) { Once a = le.Current * m; a.ValueAdd(carry); m1[idx--] = a; carry = a.Carry; } if (carry > 0) { if (idx >= 0) { m1[idx] = new Once() { Val = (byte)carry }; } else { m1.BCDbyteValue.Insert(0, new Once() { Val = (byte)carry }); } } if (!BCD.IsZero(m1)) { BCD tmp = Multiply10(m1, digit++); ans += tmp; } } return(ans); } } } catch (Exception ex) { throw new BCDException("operator * error.", l, r, ex); } }
public BCDException(string message, BCD val, Exception exception) : base(message, exception) { this.Obj = new BCD[] { val }; }
public static BCD operator -(BCD l, BCD r) { try { int maxLen = Math.Max(l.Length, r.Length); l.MaxLen = maxLen; r.MaxLen = maxLen; if (l.Sign < 0) { if (r.Sign < 0) { BCD a = Abs(l) + Abs(r); a.SetSign(-1); return(a); } else { return(r + Abs(l)); } } else { if (r.Sign < 0) { return(l + Abs(r)); } else { BCD ret = BCD.Zero; ret.MaxLen = maxLen; if (l > r) { int carry = 0; for (int i = maxLen - 1; i >= 0; i--) { Once a = l[i] - r[i]; a.ValueSub(Math.Abs(carry)); ret[i] = a; carry = a.Carry; } if (carry != 0) { ret[0].ValueSub(Math.Abs(carry)); } return(ret); } else { if (l == r) { return(BCD.Zero); } BCD a = r - l; a.SetSign(-1); return(a); } } } } catch (Exception ex) { throw new BCDException("operator - error.", l, r, ex); } }
public BCDException(string message, BCD left, BCD right, Exception exception) : base(message, exception) { this.Obj = new BCD[] { left, right }; }
public static BCD operator +(BCD l, BCD r) { try { int maxLen = Math.Max(l.Length, r.Length); l.MaxLen = maxLen; r.MaxLen = maxLen; if (l.Sign < 0) { if (r.Sign < 0) { BCD a = Abs(l) + Abs(r); a.SetSign(-1); return(a); } else { BCD a, b, c; b = Abs(l); c = Abs(r); if (b == c) { return(new BCD()); } if (b > c) { a = b - c; a.SetSign(l.Sign); } else { a = c - b; a.SetSign(r.Sign); } return(a); } } else { if (r.Sign < 0) { BCD newR = Abs(r); return(l - newR); } else { BCD ret = new BCD { MaxLen = maxLen }; int carry = 0; for (int i = maxLen - 1; i >= 0; i--) { Once a = l[i] + r[i]; a.ValueAdd(carry); ret[i] = a; carry = a.Carry; } if (carry > 0) { ret.MaxLen++; ret[0] = new Once() { Val = (byte)carry }; } return(ret); } } } catch (Exception ex) { throw new BCDException("operator + error.", l, r, ex); } }