August 04, 2008
> From: Don <nospam@nospam.com.au>
> Era Scarecrow wrote:
> >> From: Sean Kelly <sean@invisibleduck.org>
> >>
> >> bearophile wrote:
> >>> Another little story for people that think the
> >> multi-precision integers are mostly good for
> cryptography:
> >>
> http://dobbscodetalk.com/index.php?option=com_content&task=view&id=614&Itemid=
> >>
> >> Avoiding computation overflow is never a bad thing
> :)
<Snip>

> Actually that's (sort of) implemented in most hardware
> (X86, for
> instance). The overflow flag is set if you get an int
> overflow (signed
> ints). The carry flag is set if you get a uint overflow.
> 
> There are several branch instructions which make use of it.
> 
> >  Internally (Assembly) it would look something like
> this.
> >  if (a+b > 0){
> > ...
> > }
> > --becomes
> >  xor edx,edx        ;clear upper 32bits
> >  mov eax, [esp-12]  ;int a
> >  add eax, [esp-8]   ;int b
> >  adc edx, 0         ;add with carry
> 
> > 
> > --then following the compare
> > 
> >  cmp edx,0
> >  jg inside_if  ;jump if greater than 0. More likely?
> >  jb outside_if ;below 0, so it's false
> >  cmp eax,0
> >  jbe outside_if
> > inside_if:
> > ;{...}
> > outside_if:
> 
> mov eax, [esp-12];
> add eax, [esp-8];
> jo error;
> jbe outside_if;
> 
> error: throw IntegerOverflowException.
> 
> Could be added in debug builds, at least.

 Sounds promising. From what i know in C, that is never brought up, so if i wanted to handle a overflow or a carry flag i'd have to use a long long. (For a unsigned unlimited Integer math library i made, but has problems)

 Would it be possible, to have a couple operators or a special inline functions we can use to be able to use those possible overflows? I'd rather not ASM in lines where it won't be portable :(

 int carry, a = int.umax;
 b = a + a;

 if (Register.Overflow || Register.Carry){...} //possible?
 math_overflow{...}
 //or
 math_carryOn{...}
//or??
 ASM(Intel)
{
jno notOverFlow
...
}
notOverFlow:
 //or??

 long long carry, a = int.umax;
 b = a + a;
if (b>int.umax) {...}

Era



August 04, 2008
Era Scarecrow Wrote:
...

An idea is for DMD to:
- when in release mode perform as now
- When not in release mode use 4 byte numbers (or 8 byte on 64 bit CPUs) to compute operations among integral values represented in 1 or 2 bytes, use 8 bytes to perform operations among integral values represented in 4 bytes, and use 16 bytes to perform operations performed among 8 byte integral values. And control if the result can fit in the right range. I think Delphi works almost this way. In Delphi you also can define types of integer intervals:
Smally = 1 .. 25;
so the compiler (if not in release mode) controls if values are in those bounds too.
(In D you can perform something similar adding pre/post that test if that value is in the interval, but such control is done less often and you have to do it yourself manually in many parts of the code, so you don't spot the bug as soon you go out of the bounds).
In some points the compiler doesn't need to control the bounds because it can infer the value will not go out of bounds.

Bye,
bearophile