@@ -30,18 +30,18 @@ exprt get_exponent(
30
30
exprt exp_bits=extractbits_exprt (
31
31
src, spec.f +spec.e -1 , spec.f , unsignedbv_typet (spec.e ));
32
32
33
- // Exponent is in biased from (numbers from -128 to 127 are encoded with
33
+ // Exponent is in biased form (numbers from -128 to 127 are encoded with
34
34
// integer from 0 to 255) we have to remove the bias.
35
35
return minus_exprt (
36
36
typecast_exprt (exp_bits, signedbv_typet (32 )),
37
37
from_integer (spec.bias (), signedbv_typet (32 )));
38
38
}
39
39
40
- // / Gets the magnitude without hidden bit
40
+ // / Gets the fraction without hidden bit
41
41
// / \param src: a floating point expression
42
42
// / \param spec: specification for floating points
43
- // / \return An unsigned value representing the magnitude .
44
- exprt get_magnitude (const exprt &src, const ieee_float_spect &spec)
43
+ // / \return An unsigned value representing the fractional part .
44
+ exprt get_fraction (const exprt &src, const ieee_float_spect &spec)
45
45
{
46
46
return extractbits_exprt (src, spec.f -1 , 0 , unsignedbv_typet (spec.f ));
47
47
}
@@ -61,12 +61,12 @@ exprt get_significand(
61
61
{
62
62
PRECONDITION (type.id ()==ID_unsignedbv);
63
63
PRECONDITION (to_unsignedbv_type (type).get_width ()>spec.f );
64
- typecast_exprt magnitude ( get_magnitude (src, spec), type);
64
+ typecast_exprt fraction ( get_fraction (src, spec), type);
65
65
exprt exponent=get_exponent (src, spec);
66
66
equal_exprt all_zeros (exponent, from_integer (0 , exponent.type ()));
67
67
exprt hidden_bit=from_integer ((1 << spec.f ), type);
68
- plus_exprt with_hidden_bit (magnitude , hidden_bit);
69
- return if_exprt (all_zeros, magnitude , with_hidden_bit);
68
+ bitor_exprt with_hidden_bit (fraction , hidden_bit);
69
+ return if_exprt (all_zeros, fraction , with_hidden_bit);
70
70
}
71
71
72
72
// / Create an expression to represent a float or double value.
@@ -126,9 +126,9 @@ exprt floatbv_of_int_expr(const exprt &i, const ieee_float_spect &spec)
126
126
// / floating point value in decimal.
127
127
// / We are looking for d such that n * 10^d = m * 2^e, so:
128
128
// / d = log_10(m) + log_10(2) * e - log_10(n)
129
- // / m -- the magnitude -- should be between 1 and 2 so log_10(m)
129
+ // / m -- the fraction -- should be between 1 and 2 so log_10(m)
130
130
// / in [0,log_10(2)].
131
- // / n -- the magnitude in base 10 -- should be between 1 and 10 so
131
+ // / n -- the fraction in base 10 -- should be between 1 and 10 so
132
132
// / log_10(n) in [0, 1].
133
133
// / So the estimate is given by:
134
134
// / d ~=~ floor(log_10(2) * e)
@@ -169,10 +169,12 @@ string_exprt string_constraint_generatort::add_axioms_from_double(
169
169
170
170
// / Add axioms corresponding to the integer part of m, in decimal form with no
171
171
// / leading zeroes, followed by '.' ('\u002E'), followed by one or more decimal
172
- // / digits representing the fractional part of m.
172
+ // / digits representing the fractional part of m. This specification is correct
173
+ // / for inputs that do not exceed 100000 and the function is unspecified for
174
+ // / other values.
173
175
// /
174
176
// / TODO: this specification is not correct for negative numbers and
175
- // / double precision and floating point value that exceed 100000
177
+ // / double precision
176
178
// / \param f: expression representing a float
177
179
// / \param ref_type: refined type for strings
178
180
// / \return a new string expression
@@ -186,33 +188,37 @@ string_exprt string_constraint_generatort::add_axioms_for_string_of_float(
186
188
// shifted is floor(f * 1e5)
187
189
exprt shifting=constant_float (1e5 , float_spec);
188
190
exprt shifted=round_expr_to_zero (floatbv_mult (f, shifting));
191
+ // Numbers with greater or equal value to the following, should use
192
+ // the exponent notation.
193
+ exprt max_non_exponent_notation=from_integer (100000 , shifted.type ());
189
194
// fractional_part is floor(f * 100000) % 100000
190
- mod_exprt fractional_part (shifted, from_integer ( 100000 , shifted. type ()) );
195
+ mod_exprt fractional_part (shifted, max_non_exponent_notation );
191
196
string_exprt fractional_part_str=
192
197
add_axioms_for_fractional_part (fractional_part, 6 , ref_type);
193
198
194
- // The axiom added to convert to integer should always been satisfiable even
195
- // when the precondition are not satisfied.
196
- mod_exprt integer_part (
197
- round_expr_to_zero (f), from_integer (1000000 , shifted.type ()));
199
+ // The axiom added to convert to integer should always be satisfiable even
200
+ // when the preconditions are not satisfied.
201
+ mod_exprt integer_part (round_expr_to_zero (f), max_non_exponent_notation);
198
202
// We should not need more than 8 characters to represent the integer
199
203
// part of the float.
200
204
string_exprt integer_part_str=add_axioms_from_int (integer_part, 8 , ref_type);
201
205
202
206
return add_axioms_for_concat (integer_part_str, fractional_part_str);
203
207
}
204
208
205
- // / add axioms for representing the fractional part of a floating point starting
209
+ // / Add axioms for representing the fractional part of a floating point starting
206
210
// / with a dot
207
- // / \param i: an integer expression
208
- // / \param max_size: a maximal size for the string
211
+ // / \param int_expr: an integer expression
212
+ // / \param max_size: a maximal size for the string, this includes the
213
+ // / potential minus sign and therefore should be greater than 2
209
214
// / \param ref_type: a type for refined strings
210
215
// / \return a string expression
211
216
string_exprt string_constraint_generatort::add_axioms_for_fractional_part (
212
- const exprt &i , size_t max_size, const refined_string_typet &ref_type)
217
+ const exprt &int_expr , size_t max_size, const refined_string_typet &ref_type)
213
218
{
214
- PRECONDITION (i.type ().id ()==ID_signedbv);
215
- const typet &type=i.type ();
219
+ PRECONDITION (int_expr.type ().id ()==ID_signedbv);
220
+ PRECONDITION (max_size>=2 );
221
+ const typet &type=int_expr.type ();
216
222
string_exprt res=fresh_string (ref_type);
217
223
exprt ten=from_integer (10 , type);
218
224
const typet &char_type=ref_type.get_char_type ();
@@ -223,11 +229,11 @@ string_exprt string_constraint_generatort::add_axioms_for_fractional_part(
223
229
224
230
// We add axioms:
225
231
// a1 : 2 <= |res| <= max_size
226
- // a2 : forall 1 <= i < size '0' < res[i] < '9'
227
- // res[0] = '.'
228
- // a3 : i = sum_j 10^j res[j] - '0 '
229
- // for all j : !(|res| = j+1 && res[j]= '0')
230
- // for all j : |res| <= j => res[j]= '0'
232
+ // a2 : starts_with_dot && no_trailing_zero && is_number
233
+ // starts_with_dot: res[0] = '.'
234
+ // is_number: forall i:[1, max_size[. '0' < res[i] < '9 '
235
+ // no_trailing_zero: forall j:[2, max_size[. !(|res| = j+1 && res[j] = '0')
236
+ // a3 : int_expr = sum_j 10^j (j < |res| ? res[j] - '0' : 0)
231
237
232
238
and_exprt a1 (res.axiom_for_is_strictly_longer_than (1 ),
233
239
res.axiom_for_is_shorter_than (max));
@@ -241,20 +247,21 @@ string_exprt string_constraint_generatort::add_axioms_for_fractional_part(
241
247
242
248
for (size_t j=1 ; j<max_size; j++)
243
249
{
250
+ // after_end is |res| <= j
244
251
binary_relation_exprt after_end (
245
252
res.length (), ID_le, from_integer (j, res.length ().type ()));
246
253
mult_exprt ten_sum (sum, ten);
247
254
248
- // sum = 10 * sum + (res[j]-'0')
255
+ // sum = 10 * sum + after_end ? 0 : (res[j]-'0')
249
256
if_exprt to_add (
250
257
after_end,
251
258
from_integer (0 , type),
252
259
typecast_exprt (minus_exprt (res[j], zero_char), type));
253
260
sum=plus_exprt (ten_sum, to_add);
254
261
255
262
and_exprt is_number (
256
- binary_relation_exprt (res[j], ID_ge, zero_char),
257
- binary_relation_exprt (res[j], ID_le, nine_char));
263
+ binary_relation_exprt (res[j], ID_ge, zero_char),
264
+ binary_relation_exprt (res[j], ID_le, nine_char));
258
265
digit_constraints.push_back (is_number);
259
266
260
267
// There are no trailing zeros except for ".0" (i.e j=2)
@@ -263,14 +270,14 @@ string_exprt string_constraint_generatort::add_axioms_for_fractional_part(
263
270
not_exprt no_trailing_zero (and_exprt (
264
271
equal_exprt (res.length (), from_integer (j+1 , res.length ().type ())),
265
272
equal_exprt (res[j], zero_char)));
266
- axioms .push_back (no_trailing_zero);
273
+ digit_constraints .push_back (no_trailing_zero);
267
274
}
268
275
}
269
276
270
277
exprt a2=conjunction (digit_constraints);
271
278
axioms.push_back (a2);
272
279
273
- equal_exprt a3 (i , sum);
280
+ equal_exprt a3 (int_expr , sum);
274
281
axioms.push_back (a3);
275
282
276
283
return res;
@@ -286,13 +293,12 @@ string_exprt string_constraint_generatort::add_axioms_for_fractional_part(
286
293
// / $d = floor(log_10(2) * e)$
287
294
// / Then $n$ can be expressed by the equation:
288
295
// / $log_10(n) = log_10(m) + log_10(2) * e - d$
289
- // / $n = f /10^d = m * 2^e / 10^d = m * 2^e / 10^(floor(log_10(2) * e))$
290
- // /
296
+ // / $n = f / 10^d = m * 2^e / 10^d = m * 2^e / 10^(floor(log_10(2) * e))$
291
297
// / TODO: For now we only consider single precision.
292
298
// / \param f: a float expression, which is positive
293
299
// / \param max_size: a maximal size for the string
294
300
// / \param ref_type: a type for refined strings
295
- // / \return a string expression
301
+ // / \return a string expression representing the float in scientific notation
296
302
string_exprt string_constraint_generatort::
297
303
add_axioms_from_float_scientific_notation (
298
304
const exprt &f, const refined_string_typet &ref_type)
@@ -308,57 +314,58 @@ string_exprt string_constraint_generatort::
308
314
exprt bin_exponent=get_exponent (f, float_spec);
309
315
310
316
// $m$ from the formula is a value between 0.0 and 2.0 represented
311
- // with values in the range 0x000000 0x0FFFFFF so 1 corresponds to 0x0800000 .
317
+ // with values in the range 0x000000 0xFFFFFF so 1 corresponds to 0x800000 .
312
318
// `bin_significand_int` represents $m * 0x800000$
313
319
exprt bin_significand_int=
314
320
get_significand (f, float_spec, unsignedbv_typet (32 ));
315
- // `bin_significand` represents $m$ it is obtained
316
- // by multiplying `binary_significand_as_int` by 1/0x800000=1.192092896e-7.
321
+ // `bin_significand` represents $m$ and is obtained
322
+ // by multiplying `binary_significand_as_int` by
323
+ // 1/0x800000 = 2^-23 = 1.1920928955078125 * 10^-7
317
324
exprt bin_significand=floatbv_mult (
318
325
floatbv_typecast_exprt (bin_significand_int, round_to_zero_expr, float_type),
319
- constant_float (1.192092896e -7 , float_spec));
326
+ constant_float (1.1920928955078125e -7 , float_spec));
320
327
321
328
// This is a first approximation of the exponent that will adjust
322
- // if the magnitude we get is greater than 10
329
+ // if the fraction we get is greater than 10
323
330
exprt dec_exponent_estimate=estimate_decimal_exponent (f, float_spec);
324
331
325
332
// Table for values of $2^x / 10^(floor(log_10(2)*x))$ where x=Range[0,128]
326
333
std::vector<double > two_power_e_over_ten_power_d_table (
327
- { 1 , 2 , 4 , 8 , 1.6 , 3.2 , 6.4 , 1.28 , 2.56 ,
328
- 5.12 , 1.024 , 2.048 , 4.096 , 8.192 , 1.6384 , 3.2768 , 6.5536 ,
329
- 1.31072 , 2.62144 , 5.24288 , 1.04858 , 2.09715 , 4.19430 , 8.38861 , 1.67772 ,
330
- 3.35544 , 6.71089 , 1.34218 , 2.68435 , 5.36871 , 1.07374 , 2.14748 , 4.29497 ,
331
- 8.58993 , 1.71799 , 3.43597 , 6.87195 , 1.37439 , 2.74878 , 5.49756 , 1.09951 ,
332
- 2.19902 , 4.39805 , 8.79609 , 1.75922 , 3.51844 , 7.03687 , 1.40737 , 2.81475 ,
333
- 5.62950 , 1.12590 , 2.25180 , 4.50360 , 9.00720 , 1.80144 , 3.60288 , 7.20576 ,
334
- 1.44115 , 2.88230 , 5.76461 , 1.15292 , 2.30584 , 4.61169 , 9.22337 , 1.84467 ,
335
- 3.68935 , 7.37870 , 1.47574 , 2.95148 , 5.90296 , 1.18059 , 2.36118 , 4.72237 ,
336
- 9.44473 , 1.88895 , 3.77789 , 7.55579 , 1.51116 , 3.02231 , 6.04463 , 1.20893 ,
337
- 2.41785 , 4.83570 , 9.67141 , 1.93428 , 3.86856 , 7.73713 , 1.54743 , 3.09485 ,
338
- 6.18970 , 1.23794 , 2.47588 , 4.95176 , 9.90352 , 1.98070 , 3.96141 , 7.92282 ,
339
- 1.58456 , 3.16913 , 6.33825 , 1.26765 , 2.53530 , 5.07060 , 1.01412 , 2.02824 ,
340
- 4.05648 , 8.11296 , 1.62259 , 3.24519 , 6.49037 , 1.29807 , 2.59615 , 5.1923 ,
341
- 1.03846 , 2.07692 , 4.15384 , 8.30767 , 1.66153 , 3.32307 , 6.64614 , 1.32923 ,
342
- 2.65846 , 5.31691 , 1.06338 , 2.12676 , 4.25353 , 8.50706 , 1.70141 });
334
+ { 1 , 2 , 4 , 8 , 1.6 , 3.2 , 6.4 , 1.28 , 2.56 ,
335
+ 5.12 , 1.024 , 2.048 , 4.096 , 8.192 , 1.6384 , 3.2768 , 6.5536 ,
336
+ 1.31072 , 2.62144 , 5.24288 , 1.04858 , 2.09715 , 4.19430 , 8.38861 , 1.67772 ,
337
+ 3.35544 , 6.71089 , 1.34218 , 2.68435 , 5.36871 , 1.07374 , 2.14748 , 4.29497 ,
338
+ 8.58993 , 1.71799 , 3.43597 , 6.87195 , 1.37439 , 2.74878 , 5.49756 , 1.09951 ,
339
+ 2.19902 , 4.39805 , 8.79609 , 1.75922 , 3.51844 , 7.03687 , 1.40737 , 2.81475 ,
340
+ 5.62950 , 1.12590 , 2.25180 , 4.50360 , 9.00720 , 1.80144 , 3.60288 , 7.20576 ,
341
+ 1.44115 , 2.88230 , 5.76461 , 1.15292 , 2.30584 , 4.61169 , 9.22337 , 1.84467 ,
342
+ 3.68935 , 7.37870 , 1.47574 , 2.95148 , 5.90296 , 1.18059 , 2.36118 , 4.72237 ,
343
+ 9.44473 , 1.88895 , 3.77789 , 7.55579 , 1.51116 , 3.02231 , 6.04463 , 1.20893 ,
344
+ 2.41785 , 4.83570 , 9.67141 , 1.93428 , 3.86856 , 7.73713 , 1.54743 , 3.09485 ,
345
+ 6.18970 , 1.23794 , 2.47588 , 4.95176 , 9.90352 , 1.98070 , 3.96141 , 7.92282 ,
346
+ 1.58456 , 3.16913 , 6.33825 , 1.26765 , 2.53530 , 5.07060 , 1.01412 , 2.02824 ,
347
+ 4.05648 , 8.11296 , 1.62259 , 3.24519 , 6.49037 , 1.29807 , 2.59615 , 5.1923 ,
348
+ 1.03846 , 2.07692 , 4.15384 , 8.30767 , 1.66153 , 3.32307 , 6.64614 , 1.32923 ,
349
+ 2.65846 , 5.31691 , 1.06338 , 2.12676 , 4.25353 , 8.50706 , 1.70141 });
343
350
344
351
// Table for values of $2^x / 10^(floor(log_10(2)*x))$ where x=Range[-128,-1]
345
352
std::vector<double > two_power_e_over_ten_power_d_table_negatives (
346
- { 2.93874 , 5.87747 , 1.17549 , 2.35099 , 4.70198 , 9.40395 , 1.88079 , 3.76158 ,
347
- 7.52316 , 1.50463 , 3.00927 , 6.01853 , 1.20371 , 2.40741 , 4.81482 , 9.62965 ,
348
- 1.92593 , 3.85186 , 7.70372 , 1.54074 , 3.08149 , 6.16298 , 1.23260 , 2.46519 ,
349
- 4.93038 , 9.86076 , 1.97215 , 3.94430 , 7.88861 , 1.57772 , 3.15544 , 6.31089 ,
350
- 1.26218 , 2.52435 , 5.04871 , 1.00974 , 2.01948 , 4.03897 , 8.07794 , 1.61559 ,
351
- 3.23117 , 6.46235 , 1.29247 , 2.58494 , 5.16988 , 1.03398 , 2.06795 , 4.13590 ,
352
- 8.27181 , 1.65436 , 3.30872 , 6.61744 , 1.32349 , 2.64698 , 5.29396 , 1.05879 ,
353
- 2.11758 , 4.23516 , 8.47033 , 1.69407 , 3.38813 , 6.77626 , 1.35525 , 2.71051 ,
354
- 5.42101 , 1.08420 , 2.16840 , 4.33681 , 8.67362 , 1.73472 , 3.46945 , 6.93889 ,
355
- 1.38778 , 2.77556 , 5.55112 , 1.11022 , 2.22045 , 4.44089 , 8.88178 , 1.77636 ,
356
- 3.55271 , 7.10543 , 1.42109 , 2.84217 , 5.68434 , 1.13687 , 2.27374 , 4.54747 ,
357
- 9.09495 , 1.81899 , 3.63798 , 7.27596 , 1.45519 , 2.91038 , 5.82077 , 1.16415 ,
358
- 2.32831 , 4.65661 , 9.31323 , 1.86265 , 3.72529 , 7.45058 , 1.49012 , 2.98023 ,
359
- 5.96046 , 1.19209 , 2.38419 , 4.76837 , 9.53674 , 1.90735 , 3.81470 , 7.62939 ,
360
- 1.52588 , 3.05176 , 6.10352 , 1.22070 , 2.44141 , 4.88281 , 9.76563 , 1.95313 ,
361
- 3.90625 , 7.81250 , 1.56250 , 3.12500 , 6.25000 , 1.25000 , 2.50000 , 5 });
353
+ { 2.93874 , 5.87747 , 1.17549 , 2.35099 , 4.70198 , 9.40395 , 1.88079 , 3.76158 ,
354
+ 7.52316 , 1.50463 , 3.00927 , 6.01853 , 1.20371 , 2.40741 , 4.81482 , 9.62965 ,
355
+ 1.92593 , 3.85186 , 7.70372 , 1.54074 , 3.08149 , 6.16298 , 1.23260 , 2.46519 ,
356
+ 4.93038 , 9.86076 , 1.97215 , 3.94430 , 7.88861 , 1.57772 , 3.15544 , 6.31089 ,
357
+ 1.26218 , 2.52435 , 5.04871 , 1.00974 , 2.01948 , 4.03897 , 8.07794 , 1.61559 ,
358
+ 3.23117 , 6.46235 , 1.29247 , 2.58494 , 5.16988 , 1.03398 , 2.06795 , 4.13590 ,
359
+ 8.27181 , 1.65436 , 3.30872 , 6.61744 , 1.32349 , 2.64698 , 5.29396 , 1.05879 ,
360
+ 2.11758 , 4.23516 , 8.47033 , 1.69407 , 3.38813 , 6.77626 , 1.35525 , 2.71051 ,
361
+ 5.42101 , 1.08420 , 2.16840 , 4.33681 , 8.67362 , 1.73472 , 3.46945 , 6.93889 ,
362
+ 1.38778 , 2.77556 , 5.55112 , 1.11022 , 2.22045 , 4.44089 , 8.88178 , 1.77636 ,
363
+ 3.55271 , 7.10543 , 1.42109 , 2.84217 , 5.68434 , 1.13687 , 2.27374 , 4.54747 ,
364
+ 9.09495 , 1.81899 , 3.63798 , 7.27596 , 1.45519 , 2.91038 , 5.82077 , 1.16415 ,
365
+ 2.32831 , 4.65661 , 9.31323 , 1.86265 , 3.72529 , 7.45058 , 1.49012 , 2.98023 ,
366
+ 5.96046 , 1.19209 , 2.38419 , 4.76837 , 9.53674 , 1.90735 , 3.81470 , 7.62939 ,
367
+ 1.52588 , 3.05176 , 6.10352 , 1.22070 , 2.44141 , 4.88281 , 9.76563 , 1.95313 ,
368
+ 3.90625 , 7.81250 , 1.56250 , 3.12500 , 6.25000 , 1.25000 , 2.50000 , 5 });
362
369
363
370
// bias_table used to find the bias factor
364
371
exprt conversion_factor_table_size=from_integer (
@@ -392,7 +399,7 @@ string_exprt string_constraint_generatort::
392
399
plus_exprt (dec_exponent_estimate, from_integer (1 , int_type)),
393
400
dec_exponent_estimate);
394
401
395
- // `dec_significand` is divided by 10 if it exeeds 10
402
+ // `dec_significand` is divided by 10 if it exceeds 10
396
403
dec_significand=if_exprt (
397
404
estimate_too_small,
398
405
floatbv_mult (dec_significand, constant_float (0.1 , float_spec)),
@@ -409,9 +416,12 @@ string_exprt string_constraint_generatort::
409
416
exprt shifted_float=
410
417
round_expr_to_zero (floatbv_mult (fractional_part, shifting));
411
418
419
+ // Numbers with greater or equal value to the following, should use
420
+ // the exponent notation.
421
+ exprt max_non_exponent_notation=from_integer (100000 , shifted_float.type ());
422
+
412
423
// fractional_part_shifted is floor(f * 100000) % 100000
413
- mod_exprt fractional_part_shifted (
414
- shifted_float, from_integer (100000 , shifted_float.type ()));
424
+ mod_exprt fractional_part_shifted (shifted_float, max_non_exponent_notation);
415
425
416
426
string_exprt string_fractional_part=add_axioms_for_fractional_part (
417
427
fractional_part_shifted, 6 , ref_type);
@@ -421,7 +431,7 @@ string_exprt string_constraint_generatort::
421
431
string_exprt string_expr_with_fractional_part=add_axioms_for_concat (
422
432
string_expr_integer_part, string_fractional_part);
423
433
424
- // string_expr_with_E = concat(string_magnitude , string_lit_E)
434
+ // string_expr_with_E = concat(string_fraction , string_lit_E)
425
435
string_exprt string_expr_with_E=add_axioms_for_concat_char (
426
436
string_expr_with_fractional_part,
427
437
from_integer (' E' , ref_type.get_char_type ()));
@@ -434,7 +444,7 @@ string_exprt string_constraint_generatort::
434
444
return add_axioms_for_concat (string_expr_with_E, exponent_string);
435
445
}
436
446
437
- // / add axioms corresponding to the scientific representation of floating point
447
+ // / Add axioms corresponding to the scientific representation of floating point
438
448
// / values
439
449
// / \param f: a function application expression
440
450
// / \return a new string expression
0 commit comments