source: to-imperative/trunk/library/Arithm/mult.cc @ 1010

Last change on this file since 1010 was 1010, checked in by pooh, 18 years ago
  • More work on long arithmetic.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 2.1 KB
Line 
1// $Source$
2// $Revision: 1010 $
3// $Date: 2003-07-15 12:12:14 +0000 (Tue, 15 Jul 2003) $
4// $Author: pooh $
5
6#include <rf_core.hh>
7#include <rf_short_int.hh>
8#include <rf_integer.ih>
9#include <inttypes.h>
10#include <gmp.h>
11
12namespace refal
13{
14
15using namespace rfrt;
16using namespace rftype;
17
18namespace Arithm
19{
20
21RF_FUNC (_a_, (RF_ARG s_Int1, s_Int2), (RF_RES s_Int))
22
23  Term* p_Int1 = s_Int1.get_first();
24  Term* p_Int2 = s_Int2.get_first();
25
26  intptr_t int1;
27  intptr_t int2;
28  Expr result;
29
30  if (p_Int1->get_type() == type_short_int) {
31    int1 = ((ShortInt*)p_Int1)->to_int();
32    if (p_Int2->get_type() == type_short_int) {
33      int2 = ((ShortInt*)p_Int2)->to_int();
34      if (imaxabs(int1) < INTPTR_MAX / imaxabs(int2)) {
35        result = ShortInt::create_expr(int1 * int2);
36      } else {
37        result = Integer::create_expr(int1);
38        Integer* res = static_cast<Integer*>(result.get_first());
39        mpz_t* resp = res->get_mpz_ptr();
40        mpz_mul_si(*resp, *resp, int2);
41      }
42    } else if (p_Int2->get_type() == type_int) {
43      result = Integer::create_expr(int1);
44      Integer* res = static_cast<Integer*>(result.get_first());
45      mpz_t* resp = res->get_mpz_ptr();
46      Integer* i2 = static_cast<Integer*>(p_Int2);
47      mpz_t* i2p = i2->get_mpz_ptr();
48      mpz_mul(*resp, *resp, *i2p);
49    } else {
50      RF_LIB_ERROR("Invalid argument");
51    }
52  } else if (p_Int1->get_type() == type_int) {
53    Integer* i1 = static_cast<Integer*>(p_Int1);
54    mpz_t* i1p = i1->get_mpz_ptr();
55    if (p_Int2->get_type() == type_short_int) {
56      int2 = ((ShortInt*)p_Int2)->to_int();
57      result = Integer::create_expr(int2);
58      Integer* res = static_cast<Integer*>(result.get_first());
59      mpz_t* resp = res->get_mpz_ptr();
60      mpz_mul(*resp, *resp, *i1p);
61    } else if (p_Int2->get_type() == type_int) {
62      result = Integer::create_expr(0);
63      Integer* res = static_cast<Integer*>(result.get_first());
64      mpz_t* resp = res->get_mpz_ptr();
65      Integer* i2 = static_cast<Integer*>(p_Int2);
66      mpz_t* i2p = i2->get_mpz_ptr();
67      mpz_mul(*resp, *i1p, *i2p);
68    } else {
69      RF_LIB_ERROR("Invalid argument");
70    }
71  } else {
72    RF_LIB_ERROR("Invalid argument");
73  }
74  s_Int = result;
75RF_END
76}
77
78}
Note: See TracBrowser for help on using the repository browser.