@@ -210,7 +210,7 @@ struct Fp(uint size)
210210 }
211211 else
212212 {
213- if (integer == integer.init )
213+ if (! integer)
214214 return ;
215215 this .exponent = isize - size;
216216 if (! normalizedInteger)
@@ -401,7 +401,7 @@ struct Fp(uint size)
401401 T opCast (T)() nothrow const
402402 if (is (Unqual! T == bool ))
403403 {
404- return coefficient != 0 ;
404+ return exponent || coefficient ;
405405 }
406406
407407 // /
@@ -531,23 +531,51 @@ struct Fp(uint size)
531531 }
532532
533533 // /
534- T opCast (T : Fp! newCoefficientSize , size_t newCoefficientSize )() nothrow const
535- if (newCoefficientSize != size)
534+ T opCast (T : Fp! newSize , size_t newSize )() nothrow const
535+ if (newSize != size)
536536 {
537- Fp! newCoefficientSize ret = void ;
538- if (_expect(isSpecial, false ))
537+ Fp! newSize ret;
538+ ret.sign = this .sign;
539+ if (_expect(this .isSpecial, false ))
539540 {
540541 ret.exponent = ret.exponent.max;
541542 ret.coefficient = !! this .coefficient;
543+ return ret;
542544 }
543- else
545+ if ( ! this )
544546 {
545- ret = Fp! newCoefficientSize(this .coefficient, true );
546- // TODO: exponent overflow / underflow
547- // with care of special values
548- ret.exponent = ret.exponent + this .exponent;
547+ return ret;
549548 }
549+
550+ ret = Fp! newSize(this .coefficient, true );
550551 ret.sign = this .sign;
552+ static if (newSize < size)
553+ {
554+ // underflow
555+ if (this .exponent == this .exponent.min && ! ret.coefficient)
556+ {
557+ ret.exponent = 0 ;
558+ return ret;
559+ }
560+ }
561+
562+ import mir.checkedint: adds;
563+ // / overflow
564+ bool overflow;
565+ ret.exponent = adds(ret.exponent, this .exponent, overflow);
566+ if (_expect(overflow, false ))
567+ {
568+ // overflow
569+ static if (newSize < size)
570+ {
571+ assert (this .exponent > 0 );
572+ }
573+ // underflow
574+ else
575+ {
576+ assert (this .exponent < 0 );
577+ }
578+ }
551579 return ret;
552580 }
553581
0 commit comments