Darian Miller 361 Posted September 28, 2020 I imagine one of the biggest problems of being self-taught is missing out on some well-documented practices. Well, I confess that I did not know about the use of double-dabble to quickly manually convert a base-2 representation to base-10, for example: 1001000110 to 582. Quick blog post published today: https://www.ideasawakened.com/post/double-dabble-and-conversions-from-base-10-and-base-2-number-systems 2 Share this post Link to post
dummzeuch 1505 Posted September 29, 2020 Hm, I always convert to hex as an intermediary step (and actually prefer hex constants in source code). and I can still do binary to hex and back in my head, back from the C64 times. 1 Share this post Link to post
Anders Melander 1786 Posted September 29, 2020 1 hour ago, dummzeuch said: I can still do binary to hex and back in my head You mean to say that you've memorized all the 16 hex digits? Wow Share this post Link to post
Guest Posted September 29, 2020 I have mountain of things that need to be done right now, but what to say !, i am bored to hell and looking something to do away from what is needed, so. @Darian Miller this is special for you program BinaryNumbers; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; function IntToBin(Value: Integer; Digits: Integer = 0): string; var I, Len: Integer; Negative: Boolean; begin // Set boundaries and limits Negative := Value < 0; if Negative then Value := 0 - Value; Len := 1; while (1 shl Len) <= Value do Len := Len + 1; if Digits < 1 then Digits := 1 else if Digits > 31 then Digits := 31; if Len < Digits then Len := Digits; Len := Len + Ord(Negative); // Do translate SetLength(Result, Len); I := 0; while Value > 0 do begin Result[Len - I] := Char((Value and 1) + Ord('0')); Value := Value shr 1; Inc(I); end; // Fill leading zeroes, up to Digits, and add signal while I < Digits do begin Result[Len - I] := '0'; Inc(I); end; if Negative then Result[1] := '-'; end; function DoubleToBin(Value: Double; Digits: Integer = 0; FracDigits: Integer = 8): string; var I, Len: Integer; IntPart: Integer; FractalPart: Double; begin IntPart := Trunc(Value); Result := IntToBin(IntPart, Digits); // Prepare result for fractal part FractalPart := Value - IntPart; if FractalPart < 0 then FractalPart := 0 - FractalPart; if (FracDigits > 0) or (FractalPart > 0) then Result := Result + '.'; // Set boundaries and limits for fractal part Len := 0; if FracDigits < 0 then FracDigits := 0; if Len < FracDigits then Len := FracDigits; if Len = 0 then Exit; // Do translate I := Length(Result); SetLength(Result, I + Len); Inc(FracDigits, I); while (FractalPart > 0) and (I < FracDigits) do begin FractalPart := FractalPart * 2; Inc(I); Result[I] := Char(Ord(FractalPart >= 1) + Ord('0')); if FractalPart >= 1 then FractalPart := FractalPart - 1; end; // Fill trailing zeroes, up to FracDigits while (I < FracDigits) do begin Inc(I); Result[I] := '0'; end; end; function BinaryToInt(const Value: string): Integer; procedure NotValidOfIntegerException; begin raise Exception.Create('BinaryToInt Error : ''' + Value + ''' is not valid binary integer'); end; var I, S, Len: Integer; Negative: Boolean; begin // Check validity and set boundaries Result := 0; Len := Length(Value); if Len = 0 then Exit; Negative := Value[1] = '-'; if Negative then begin if Len = 1 then NotValidOfIntegerException; S := 2; end else S := 1; for I := S to Len do if (Value[I] <> '0') and (Value[I] <> '1') then NotValidOfIntegerException; // calculate for I := S to Len do Result := Result + (Ord(Value[I]) - Ord('0')) shl (Len - I); if Negative then Result := 0 - Result; end; // simple and naive conversion function, though the fractal part is OK with the standard // not IEEE X compatible as the integer part is considered as simple integer // in IEEE standards the integral part should be exponentially calculated and not converted into decimal function BinaryToDouble(const Value: string): Double; procedure NotValidBinaryOfDoubleException; begin raise Exception.Create('BinaryToDouble Error : ''' + Value + ''' is not valid binary double'); end; var I, P, Len: Integer; IntPart: string; Temp: Double; begin // Check validity and set boundaries Result := 0; Len := Length(Value); if Len = 0 then Exit; P := Pos('.', Value); if (P = 1) or (P = Len) then NotValidBinaryOfDoubleException; SetLength(IntPart, P - 1); for I := 1 to P - 1 do IntPart[I] := Value[I]; for I := P + 1 to Len do if (Value[I] <> '0') and (Value[I] <> '1') then NotValidBinaryOfDoubleException; // calculate fractal part if P > 0 then begin Inc(P); Temp := 1 / 2; for I := P to Len do begin Result := Result + Temp * (Ord(Value[I]) - Ord('0')); Temp := Temp / 2; end; end; // build final result if Value[1] = '-' then Result := 0 - Result; Result := Result + BinaryToInt(IntPart); end; begin Writeln(DoubleToBin(582.24, 16)); Writeln(DoubleToBin(582.24,0, 2)); Writeln(DoubleToBin(-582.24, 0, 32)); Writeln(DoubleToBin(-10/3,0,24)); Writeln(FloatToStr(BinaryToDouble('-11.010101010101010101010101'))); Writeln(FloatToStr(BinaryToDouble('0000001001000110.00111101'))); Writeln(FloatToStr(BinaryToDouble('1001000110.00'))); Writeln(FloatToStr(BinaryToDouble('-1001000110.00111101011100001010001111010111'))); Readln; end. the result 0000001001000110.00111101 1001000110.00 -1001000110.00111101011100001010001111010111 -11.010101010101010101010101 -3.33333331346512 582.23828125 582 -582.239999999991 Hope you find it useful and for your quest after converting the fractal part then it is way simple that what you think, start with 1/2 and half it with each step, waling the bit from the left to the right. ps : not fully tested but i think i mostly got it right at first try, if anyone find bug or have better and enhanced version of it or any other, please share here. Share this post Link to post
Anders Melander 1786 Posted September 29, 2020 Ummm. I must be missing some deeper meaning here but what is the point of pretending that an integer values isn't already stored in binary format? I mean, I could understand if you were trying to implement bin/dec conversion on a denary computer but other than that this sounds like an algorithm for people that doesn't have access to computers. Share this post Link to post
Darian Miller 361 Posted September 29, 2020 8 hours ago, dummzeuch said: Hm, I always convert to hex as an intermediary step (and actually prefer hex constants in source code). and I can still do binary to hex and back in my head, back from the C64 times. Thanks, that was also pointed out by others online and it will likely be in a follow-up article. I simply didn't know about the double-dabble trick and thought it was kinda cool. I don't do these number system conversions enough to be able to convert any lengthy amount in my head yet. Lately I've been attempting to spend a lot more time learning rather than just always doing. Unfortunately, I was always the work-harder and not the work-smarter type. Few could out-work me, but many could out-smart me. I want to combine the two, and maybe the next buyout will have an extra zero or two behind it. Or, I'll simply enjoy it more. Either way, it's a win. Share this post Link to post
Darian Miller 361 Posted September 29, 2020 5 hours ago, Kas Ob. said: I have mountain of things that need to be done right now, but what to say !, i am bored to hell and looking something to do away from what is needed, so. @Darian Miller this is special for you Literally LOL. Thanks. I'll try to absorb it! 🙂 Share this post Link to post
limelect 48 Posted October 12, 2020 (edited) @Darian Miller Just for fun JUST FOUND NO BRACKET IN MY SOURCE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! what an HTML PAGE !!!!! plz fix x:= StrToInt(s); <<<<<<<<<<<< cannot put bracket i unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, JvExStdCtrls, JvEdit, JvValidateEdit, Vcl.Mask, JvExMask, JvSpin; type TForm1 = class(TForm) Button1: TButton; JvValidateEdit1: TJvValidateEdit; Label1: TLabel; Button2: TButton; JvValidateEdit2: TJvValidateEdit; Label2: TLabel; Button3: TButton; JvValidateEdit3: TJvValidateEdit; JvSpinEdit1: TJvSpinEdit; Label3: TLabel; Button4: TButton; Label4: TLabel; Label5: TLabel; Edit1: TEdit; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin Label1.Caption:='Answer'; Label2.Caption:='Answer'; Label3.Caption:='Answer'; end; procedure TForm1.Button1Click(Sender: TObject); //to binary var i,x:integer; ans:string; begin ans:=''; i:= JvValidateEdit1.Value; while i>0 do begin ans:=IntToStr(i mod 2) + ans ; i :=i div 2; //ans:=IntToStr(i mod 2)+ans ; //i :=i div 2; end; Label1.Caption:=ans; end; procedure TForm1.Button2Click(Sender: TObject); // to decimal var s:string; i,ans:Integer; begin ans:=1; s:=JvValidateEdit2.Text; for I := 1 to length(s)-1 do ans:=(ans*2) +StrToInt(s[i+1]); Label2.Caption:=IntToStr(ans); end; procedure TForm1.Button3Click(Sender: TObject); //fraction cal var f:real; i,x:integer ; ans:string; begin ans:='0.'; f:=JvValidateEdit3.Value; for I := 1 to Round(JvSpinEdit1.Value) do begin f:=f*2; x:=Trunc(f); f:=Frac(f); ans:=ans+IntToStr(x); end; Label3.Caption:=ans; end; // https://indepth.dev/the-simple-math-behind-decimal-binary-conversion-algorithms/ procedure TForm1.Button4Click(Sender: TObject); //binary to fruction var s:string; k:Real; i,x:Integer; ans:string; begin k:=0; s:=Edit1.Text; for I :=Length(s) downto 1 do begin x:= StrToInt(s);k:=(1/2)*(x+k); end; Label5.Caption:=FloatToStr(k);end; end. object Form1: TForm1 Left = 0 Top = 0 Caption = 'Form1' ClientHeight = 283 ClientWidth = 552 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -13 Font.Name = 'Tahoma' Font.Style = [] OldCreateOrder = False OnCreate = FormCreate PixelsPerInch = 120 TextHeight = 16 object Label1: TLabel Left = 335 Top = 35 Width = 37 Height = 19 Caption = 'Label1' end object Label2: TLabel Left = 335 Top = 73 Width = 37 Height = 16 Caption = 'Label2' end object Label3: TLabel Left = 335 Top = 119 Width = 27 Height = 16 Caption = 'anse' end object Label4: TLabel Left = 187 Top = 155 Width = 16 Height = 21 Caption = '0.' Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -17 Font.Name = 'Tahoma' Font.Style = [fsBold] ParentFont = False end object Label5: TLabel Left = 335 Top = 159 Width = 27 Height = 16 Caption = 'anse' end object Button1: TButton Left = 66 Top = 32 Width = 110 Height = 25 Caption = 'To Binary' TabOrder = 0 OnClick = Button1Click end object JvValidateEdit1: TJvValidateEdit Left = 182 Top = 32 Width = 121 Height = 24 CriticalPoints.MaxValueIncluded = False CriticalPoints.MinValueIncluded = False EditText = '582' TabOrder = 1 end object Button2: TButton Left = 68 Top = 70 Width = 108 Height = 25 Caption = 'To Decimal' TabOrder = 2 OnClick = Button2Click end object JvValidateEdit2: TJvValidateEdit Left = 182 Top = 70 Width = 121 Height = 24 CriticalPoints.MaxValueIncluded = False CriticalPoints.MinValueIncluded = False EditText = '1001000110' TabOrder = 3 end object Button3: TButton Left = 66 Top = 116 Width = 110 Height = 25 Caption = 'Fruction Calc' TabOrder = 4 OnClick = Button3Click end object JvValidateEdit3: TJvValidateEdit Left = 182 Top = 117 Width = 121 Height = 24 CriticalPoints.MaxValueIncluded = False CriticalPoints.MinValueIncluded = False DisplayFormat = dfFloat DecimalPlaces = 10 EditText = '0.24' TabOrder = 5 end object JvSpinEdit1: TJvSpinEdit Left = 481 Top = 116 Width = 63 Height = 24 MaxValue = 10.000000000000000000 MinValue = 1.000000000000000000 Value = 8.000000000000000000 TabOrder = 6 end object Button4: TButton Left = 73 Top = 155 Width = 108 Height = 25 Caption = 'Binary Fruction' TabOrder = 7 OnClick = Button4Click end object Edit1: TEdit Left = 208 Top = 155 Width = 95 Height = 24 NumbersOnly = True TabOrder = 8 Text = '1011' endend Edited October 12, 2020 by limelect Share this post Link to post
Lars Fosdal 1792 Posted October 13, 2020 @limelect Press to insert code without having the editor destroying it. Share this post Link to post
limelect 48 Posted October 14, 2020 (edited) @Lars Fosdal This is a test </> [my test] Nice now I understand So if I put source I </> before the source right? Edited October 14, 2020 by limelect Share this post Link to post
sakura 45 Posted October 14, 2020 2 hours ago, limelect said: @Lars Fosdal So if I put source I </> before the source right? Take a look above the text editor, in the toolbar and look for the </> button, press that to insert code 🙂 Share this post Link to post