Mathematics

Mathematics

Byte swapping
Encryption Algorithm
Random Number Generator
Bit-wise manipulation
Duplicating the atan2 function in Delphi
Calculating periodic debt payments


Byte swapping

Question


Does anyone have the algorithms for swapping bytes between big-endian and

little-endian format.

Answer


A:

Check the function swap in Delphi Help. There is a typo in their definition,

the correct one is:



     function Swap(X) : word;



Their example is as follows:



var

  X: Word;

begin

  X := Swap($1234);   { $3412 }

end;



Swap will provide a big-endian when you feed it with a little-endian and

viceversa.



A:

To swap a 16-bit integer or word, use



   value: integer;

   value := swap(value); {builtin Pascal function}



To swap a 32-bit long, use



   value: longint;

   value := swap(value shr 16) or (longint(swap(value and $ffff)) shl 16);



I don't know what the standards are for floating point values, but if they

conform to integer and longint (my guess is they do), then you'd use (for

double):



   value: double;

   block: array[0..7] of byte absolute value;

   temp:  byte;



   for i := 0 to 3 do begin

      temp := block[i];

      block[i] := block[7-i];

      block[7-i] := temp;

   end;



If you're using real, array should be 0..5 and the for loop 0 to 2; if

you're using comp, 0..7 and 0 to 3; for single, 0..3 and 0 to 1; for

extended, 0..9 and 0 to 4.



You can also change this to a procedure that takes a pointer to the value

and the size of the value, eg. (this is off the top of my head, may need

tweaking):



   procedure swapper (valin: pointer; size: integer);

   var

      i: integer;

      temp: byte;

      val:  ^byte;

   begin

      size := size - 1;

      val := valin;

      for i := 0 to (size div 2) do begin

         temp := val[i];

         val[i] := val[size-i];

         val[size-i] := temp;

      end;

   end;



then you can call this using



   swapper (@value, sizeof(value));



(This would also work for longint, integer, etc. but swap() is more efficient.)



Note that in addition to swapping the bytes, you may have to do a format

conversion (from eg. Microsoft floating point to ANSI); I don't dabble in

floating point, so I don't know for sure.  Best thing might be to flip the

bytes and see if the other system recognizes it as the same number that

Delphi does.



A:

I had a similar problem, I was reading a TColor from disk, in RGB

format ($RRGGBB), while delphi uses BGR format.



I solved my problem by and'ing the initial number with a mask, and

retrieving the values, and then placing them into my format. eg:



color := $F03200;

r := (color and $FF0000) div $010000; {should return $F0}

g := (color and $00FF00) div $000100; {should return $32}

b := (color and $0000FF);             {should return $00}

newcolor := (b * $010000) + (g * $000100) + b;



If this works, newcolor should hold $0032F0.



A:

You will probably have to use an assembly routine something like...



var

  result : byte;



asm {

	mov cx,8

	mov ah,0

	mov al,

@do_loop

	shr al,1

	shl ah,1

	jcc @dont_set_bit  ; jump carry clear (I'm not sure if this is correct)

	xor ah,1

@dont_set_bit:

	loop do_loop

	mov result,al

}



This is more like pseudo-code (because my assembly's a little rusty).  =

If you want it to be more "portable" then you'd have to use pascal =

instead of inline assembly (you can still use SHL - bit-wise shift left =

and SHR - right).


Encryption Algorithm

Question


I would like a Delphi unit algorithm that I can compile in... not those

external DLL, 'C' source etc.

I realize that home-brewed algorithms can be relatively weak.... but

can someone just send me some algorithms to start with?

Answer


A:

        const

           C1 = 52845;   {Used for encryption of Master Password string}

           C2 = 11719;

           Key = 1234;



        { Standard Decryption algorithm - Copied from Borland}

        function Decrypt(const S: String; Key: Word): String;

        var

          I: byte;

        begin

          Result[0] := S[0];

          for I := 1 to Length(S) do begin

            Result[I] := char(byte(S[I]) xor (Key shr 8));

            Key := (byte(S[I]) + Key) * C1 + C2;

          end;

        end;



        { Standard Encryption algorithm - Copied from Borland}

        function Encrypt(const S: String; Key: Word): String;

        Var

          I: byte;

        begin

          Result[0] := S[0];

          for I := 1 to Length(S) do begin

            Result[I] := char(byte(S[I]) xor (Key shr 8));

            Key := (byte(Result[I]) + Key) * C1 + C2;

          end;

        end;


Random Number Generator

Question


Does anyone know of a way to improve the random number generator in

Delphi?  The generator used in Delphi is pretty much the same as

that in VB or C.

Answer


A:

Following is an assembler version of a random number generator

which I got from Dr Dobbs Journal or one of the other magazines

several years ago. Try it and see if it gives you any better results.



function __R( range : word ) : word; assembler;

	asm

		mov		ax,	Word(System.RandSeed)   { DS:[003eH] }

		mov		bx, Word(System.RandSeed+2)	{ DS:[0040H] }

		mov		cx,	ax

		mul		CS:word ptr [0598H]

		shl		cx,	1

		shl		cx,	1

		shl		cx,	1

		add		ch, cl

		add		dx, cx

		add		dx,	bx

		shl		bx,	1

		shl		bx,	1

		add		dx,	bx

		add		dh,	bl

		mov		cx,	0005H

	@1:

		shl		bx,	1

		loop	@1

		add		dh,	bl

		add		ax,	0001

		adc		dx,	0000

		mov   word(System.RandSeed), ax 	{ [003eH],	ax }

		mov  	word(System.RandSeed+2), dx { [0040H],	dx }



		xor		ax,	ax

		mov		bx,	range

		or		bx,	bx

		je		@2



		xchg	dx,	ax

		div		bx

		xchg	dx,	ax

	@2:

end;


Bit-wise manipulation

Question




Answer


{******************************************

TheBit parameter is counted from 0..31

******************************************}



unit Bitwise;



interface

  function IsBitSet(const val: longint; const TheBit: byte): boolean;

  function BitOn(const val: longint; const TheBit: byte): LongInt;

  function BitOff(const val: longint; const TheBit: byte): LongInt;

  function BitToggle(const val: longint; const TheBit: byte): LongInt;



implementation



function IsBitSet(const val: longint; const TheBit: byte): boolean;

begin

  result := (val and (1 shl TheBit)) <> 0;

end;



function BitOn(const val: longint; const TheBit: byte): LongInt;

begin

  result := val or (1 shl TheBit);

end;



function BitOff(const val: longint; const TheBit: byte): LongInt;

begin

  result := val and ((1 shl TheBit) xor $FFFFFFFF);

end;



function BitToggle(const val: longint; const TheBit: byte): LongInt;

begin

  result := val xor (1 shl TheeBit);

end;



end.




Duplicating the atan2 function in Delphi

Question


How to program the atan2 function?

Answer


function sgn (a : real) : real;

begin

  if a < 0  then  sgn := -1;

            else  sgn :=  1;

end;



function atan2 (y, x : real) : real;

begin

  if x > 0       then  atan2 := arctan (y/x)

  else if x < 0  then  atan2 := arctan (y/x) + pi

  else                 atan2 := pi/2 * sgn (y);

end;



{

I did this a while ago when moving from FORTRAN to Pascal.

I think I tested it way back then but my memory is fading

good luck.

}

Nathan



-------------------------------------------------------------------------------



From: Terje Mathisen 

Subject: Re: How to duplicate C function ATAN2 in Delphi?

Date: 18 May 1995 19:25:10 GMT



I think you should seriously consider using the FPATAN instruction for this!



This x87 opcode implements an IEEE-compliant ATAN2() function, with full extended 

precision, and the hardware will handle all the special cases for you.



If you have numeric exceptions enabled, and input bogus values, the x87 chip will 

raise the appropriate signal, without the need for upfront testing of parameters.



A BP/TP/Delphi-compatible version would look like this:



Function atan2(y : extended; x : extended): Extended;

Assembler;

asm

  fld [y]

  fld [x]

  fpatan

end;



Total execution time is less than 200 cycles on a Pentium, with less than 1 ulp 

maximum error, unless you have a Pentium with the FDIV bug, where it could fail 

almost anywhere after the first 15-20 OK bits!  :-)



The library function ArcTan(x) is implemented as fpatan(1.0,x), as long as you 

compile with IEEE reals {$N+} set.



Terje



-- 

-Terje Mathisen (include std disclaimer) 

"almost all programming can be viewed as an exercise in caching"



-------------------------------------------------------------------------------



This is a potential problem as the win87em.dll or the sw

lib does not work with this so the sw will fail on all non

CoP equipped boxes.



--

Name:        Dr Jon Jenkins

Internet:    jenkinsj@ozy.dec.com




Calculating periodic debt payments

Question


How to calculate periodic debt payments?

Answer


PAYMENT()



Returns the periodic amount required to repay a debt.



function payment(princ, int, term: double): double;

var temp: double;

begin

  int := int / 100;

  temp := exp(ln(int + 1) * term);

  result := princ * ((int * temp) / (temp - 1));

end;



Syntax



PAYMENT(, , )







The original amount to be repaid over time.







The interest rate per period expressed as a positive decimal 

number. Specify the interest rate in the same time increment 

as  the term.  It is to be expressed as a percentage.  The 

number is divided by 100 inside the function.  







The number of payments. Specify the term in the same time 

increment as the interest.



Description



Use PAYMENT(#) to calculate the periodic amount (payment) 

required to repay a loan or investment of  

amount in   payments. PAYMENT(#) returns a numeric 

value based on a fixed interest rate compounding over a fixed 

length of  time. If  is positive, PAYMENT(#) 

returns a positive number. If  is negative, 

PAYMENT(#) returns a  negative number. Express the interest 

rate as a decimal. For example, if the annual interest rate is 

9.5%,  is 9.5 for  payments made annually.



Express  and  in the same time 

increment. For example, if the payments are monthly, express 

the  interest rate per month, and the number of payments in 

months. You would express an annual interest rate of#9.5%, for 

example,  as 9.5/12, which is the 9.5% divided by 12#months. 

The formula used to calculate PAYMENT(#) is as follows:



                           term

              int*(1 + int)^

pmt = princ * -------------------

                       term

              (1 + int)^     -  1



where int = rate / 100 (as a percentage).



For the monthly payment required to repay a principal amount of 

$16860.68 in five years, at 9% interest, the formula expressed 

as  a dBASE expression looks like this:



MyVar := PAYMENT(16860.68, 9/12, 60)       {Returns 350.00}





DISCLAIMER: You have the right to use this technical information

subject to the terms of the No-Nonsense License Statement that

you received with the Borland product to which this information

pertains.




Close    To Top
  • Prev Article-Programming:
  • Next Article-Programming:
  • Now: Tutorial for Web and Software Design > Programming > delphi > Programming Content
    Photoshop Tutorial
     

    Special Effect

      3D Effect
      Photoshop Articles
    Programming Tutorial
     

    C/C++ Tutorial

      Visual Basic
      C# Tutorial
    Database Tutorial
     

    MySQL Tutorial

      MS SQL Tutorial
      Oracle Tutorial
    Geek Tutorial
     

    Blogging Tutorial

      RSS Tutorial
      Podcasting Tutorial
    Graphic Design Tutorial
      Coreldraw Tutorial
      Illustrator Tutorial
      3D Tutorials
    Webmaster Articles
     

    Domain Service

      Web Hosting
      Site Promotion
    Java Tutorial/ Articles
     

    Java Servlets

      JavaEE Tutorial
     

    JavaBeans Tutorial

    XML Tutorial/ Articles
     

    XML Style

      AJAX Tutorial
      XML Mobile
    Flash Tutorial/ Articles
     

    Flash Video

      Action Script
      Flash Articles
    OS Tutorial/ Articles
      Linux Tutorial
      Symbian Tutorial
      MacOS Tutorial
    Personal Tech
      Hardware Tutorial
      Software Tutorial
      Online Auction