GCC Wikia
Advertisement

このページを編集する際は,編集に関する方針に従ってください.[]

概要[]

引数[]

実装[]

 660 /* Calculate R = A * B.  Return true if the result may be inexact.  */
661 
662 static bool
663 do_multiply (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
664              const REAL_VALUE_TYPE *b)
665 {
666   REAL_VALUE_TYPE u, t, *rr;
667   unsigned int i, j, k;
668   int sign = a->sign ^ b->sign;
669   bool inexact = false;
670 

~
~

671   switch (CLASS2 (a->cl, b->cl))
672     {
673     case CLASS2 ([[rvc_zero>enum real_value_class]], [[rvc_zero>enum real_value_class]]):
674     case CLASS2 ([[rvc_zero>enum real_value_class]], [[rvc_normal>enum real_value_class]]):
675     case CLASS2 ([[rvc_normal>enum real_value_class]], [[rvc_zero>enum real_value_class]]):
 676       /* +-0 * ANY = 0 with appropriate sign.  */
677       get_zero (r, sign);
678       return false;
679 
680     case CLASS2 ([[rvc_zero>enum real_value_class]], [[rvc_nan>enum real_value_class]]):
681     case CLASS2 ([[rvc_normal>enum real_value_class]], [[rvc_nan>enum real_value_class]]):
682     case CLASS2 ([[rvc_inf>enum real_value_class]], [[rvc_nan>enum real_value_class]]):
683     case CLASS2 ([[rvc_nan>enum real_value_class]], [[rvc_nan>enum real_value_class]]):
 684       /* ANY * NaN = NaN.  */
685       *r = *b;
686       r->sign = sign;
687       return false;
688 
689     case CLASS2 ([[rvc_nan>enum real_value_class]], [[rvc_zero>enum real_value_class]]):
690     case CLASS2 ([[rvc_nan>enum real_value_class]], [[rvc_normal>enum real_value_class]]):
691     case CLASS2 ([[rvc_nan>enum real_value_class]], [[rvc_inf>enum real_value_class]]):
 692       /* NaN * ANY = NaN.  */
693       *r = *a;
694       r->sign = sign;
695       return false;
696 
697     case CLASS2 ([[rvc_zero>enum real_value_class]], [[rvc_inf>enum real_value_class]]):
698     case CLASS2 ([[rvc_inf>enum real_value_class]], [[rvc_zero>enum real_value_class]]):
 699       /* 0 * Inf = NaN */
700       get_canonical_qnan (r, sign);
701       return false;
702 
703     case CLASS2 ([[rvc_inf>enum real_value_class]], [[rvc_inf>enum real_value_class]]):
704     case CLASS2 ([[rvc_normal>enum real_value_class]], [[rvc_inf>enum real_value_class]]):
705     case CLASS2 ([[rvc_inf>enum real_value_class]], [[rvc_normal>enum real_value_class]]):
 706       /* Inf * Inf = Inf, R * Inf = Inf */
707       get_inf (r, sign);
708       return false;
709 
710     case CLASS2 ([[rvc_normal>enum real_value_class]], [[rvc_normal>enum real_value_class]]):
711       break;
712 
713     default:
714       gcc_unreachable ();
715     }
716 

~
~
*[[rvc_normal>enum real_value_class]]*[[rvc_normal>enum real_value_class]]ならば

~
*掛ける数、掛けられる数を上書きしないための処理

717   if (r == a || r == b)
718     rr = #&x26;t;
719   else
720     rr = r;
721   get_zero (rr, 0);
722 

~
*筆算方式(?)でやるみたい
*A,...,Hがsigの一要素の半分となる

 723   /* Collect all the partial products.  Since we don't have sure access
 724      to a widening multiply, we split each long into two half-words.
 725 
 726      Consider the long-hand form of a four half-word multiplication:
 727 
 728                  A  B  C  D
 729               *  E  F  G  H
 730              --------------
 731                 DE DF DG DH
 732              CE CF CG CH
 733           BE BF BG BH
 734        AE AF AG AH
 735 
 736      We construct partial products of the widened half-word products
 737      that are known to not overlap, e.g. DF+DH.  Each such partial
 738      product is given its proper exponent, which allows us to sum them
 739      and obtain the finished product.  */
740 
741   for (i = 0; i < SIGSZ * 2; ++i)
742     {

*仮数部から塊を一つ取る
**塊はsigの要素の半分

743       unsigned long ai = a->sig[i / 2];
744       if (i & 1)
745         ai >>= HOST_BITS_PER_LONG / 2;
746       else
747         ai &= ((unsigned long)1 << (HOST_BITS_PER_LONG / 2)) - 1;
748 
749       if (ai == 0)
750         continue;
751 

*掛ける数もsigの要素の半分なので2回繰り返す

752       for (j = 0; j < 2; ++j)
753         {
754           int exp = (REAL_EXP (a) - (2*SIGSZ-1-i)*(HOST_BITS_PER_LONG/2)
755                      + (REAL_EXP (b) - (1-j)*(HOST_BITS_PER_LONG/2)));
756 
757           if (exp > MAX_EXP)
758             {
759               get_inf (r, sign);
760               return true;
761             }
762           if (exp < -MAX_EXP)
763             {
 764               /* Would underflow to zero, which we shouldn't bother adding.  */
765               inexact = true;
766               continue;
767             }
768 
769           memset (&u, 0, sizeof (u));
770           u.cl = [[rvc_normal>enum real_value_class]];
771           SET_REAL_EXP (&u, exp);
772 

*掛ける数の塊を取り出す

773           for (k = j; k < SIGSZ * 2; k += 2)
774             {
775               unsigned long bi = b->sig[k / 2];
776               if (k & 1)
777                 bi >>= HOST_BITS_PER_LONG / 2;
778               else
779                 bi &= ((unsigned long)1 << (HOST_BITS_PER_LONG / 2)) - 1;
780 
781               u.sig[k / 2] = ai * bi;
782             }
783 
784           normalize (&u);
785           inexact |= do_add (rr, rr, &u, 0);
786         }
787     }
788 

~

789   rr->sign = sign;
790   if (rr != r)
791     *r = t;
792 
793   return inexact;
794 }


リンク元

Advertisement