@@ -210,7 +210,7 @@ struct Fp(uint size)
210
210
}
211
211
else
212
212
{
213
- if (integer == integer.init )
213
+ if (! integer)
214
214
return ;
215
215
this .exponent = isize - size;
216
216
if (! normalizedInteger)
@@ -401,7 +401,7 @@ struct Fp(uint size)
401
401
T opCast (T)() nothrow const
402
402
if (is (Unqual! T == bool ))
403
403
{
404
- return coefficient != 0 ;
404
+ return exponent || coefficient ;
405
405
}
406
406
407
407
// /
@@ -531,23 +531,51 @@ struct Fp(uint size)
531
531
}
532
532
533
533
// /
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)
536
536
{
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 ))
539
540
{
540
541
ret.exponent = ret.exponent.max;
541
542
ret.coefficient = !! this .coefficient;
543
+ return ret;
542
544
}
543
- else
545
+ if ( ! this )
544
546
{
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;
549
548
}
549
+
550
+ ret = Fp! newSize(this .coefficient, true );
550
551
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
+ }
551
579
return ret;
552
580
}
553
581
0 commit comments