1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//
// GENERATED FILE
//
use super::*;
use f2rust_std::*;
struct SaveVars {
ZZMULT: f64,
LOGA: f64,
LOGB: f64,
EXPNT: f64,
FIRST: bool,
}
impl SaveInit for SaveVars {
fn new() -> Self {
let mut ZZMULT: f64 = 0.0;
let mut LOGA: f64 = 0.0;
let mut LOGB: f64 = 0.0;
let mut EXPNT: f64 = 0.0;
let mut FIRST: bool = false;
FIRST = true;
Self {
ZZMULT,
LOGA,
LOGB,
EXPNT,
FIRST,
}
}
}
//$Procedure ZZMULT ( Safer multiplication )
pub fn ZZMULT(A: f64, B: f64, ctx: &mut Context) -> f2rust_std::Result<f64> {
let save = ctx.get_vars::<SaveVars>();
let save = &mut *save.borrow_mut();
//
// SPICELIB functions
//
//
// Local variables
//
//
// The bounds on the potential result of the calculation.
//
//
// First entry flag.
//
//
// Return on error.
//
if RETURN(ctx) {
save.ZZMULT = 0.0;
return Ok(save.ZZMULT);
}
//
// Participate in error tracing.
//
CHKIN(b"ZZMULT", ctx)?;
//
// Calculate the bounds parameter on first entry.
// The double precision maximum value has the form
// "d*(10**EXPNT)." The value of interest is "EXPNT."
//
if save.FIRST {
save.FIRST = false;
//
// A "floor" evaluation.
//
save.EXPNT = ((f64::log10(DPMAX()) as i32) as f64);
}
//
// If either A or B equals zero the multiplication is zero.
//
if ((A == 0.0) || (B == 0.0)) {
save.ZZMULT = 0.0;
CHKOUT(b"ZZMULT", ctx)?;
return Ok(save.ZZMULT);
}
//
// Calculate base 10 logarithms of the absolute value of the
// numerator and denominator. Recall the base 10 log of a negative
// real is a complex number (an irritating reality). Our interest
// is the magnitude of the result, not the sign.
//
// An earlier check returned if A or B equal zero.
//
save.LOGA = f64::log10(f64::abs(A));
save.LOGB = f64::log10(f64::abs(B));
//
// Local possible overflow check.
//
if ((save.LOGA + save.LOGB) > save.EXPNT) {
save.ZZMULT = 0.0;
SETMSG(
b"Numerical overflow event. Multiplier value, #1, multiplicand value, #2.",
ctx,
);
ERRDP(b"#1", A, ctx);
ERRDP(b"#2", B, ctx);
SIGERR(b"SPICE(NUMERICOVERFLOW)", ctx)?;
CHKOUT(b"ZZMULT", ctx)?;
return Ok(save.ZZMULT);
}
//
// Local possible underflow check. Accept this may occur,
// return a zero.
//
if ((save.LOGA + save.LOGB) < -(save.EXPNT - 1.0)) {
save.ZZMULT = 0.0;
CHKOUT(b"ZZMULT", ctx)?;
return Ok(save.ZZMULT);
}
//
// This operation should be safe. Probably.
//
save.ZZMULT = (A * B);
CHKOUT(b"ZZMULT", ctx)?;
Ok(save.ZZMULT)
}