Skip to content

Commit 32d0f60

Browse files
author
Vojtech Forejt
committed
Handle common floats to string operations in the model and not in the string solver
1 parent 14e140f commit 32d0f60

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

src/main/java/java/lang/String.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4266,8 +4266,9 @@ public static String valueOf(float f) {
42664266
* actual program.
42674267
*/
42684268
public static String valueOf(double d) {
4269-
// DIFFBLUE MODEL LIBRARY This is treated internally in CBMC
4270-
return CProver.nondetWithoutNullForNotModelled();
4269+
// DIFFBLUE MODEL LIBRARY we cast the number down to float because
4270+
// the string solver only knows how to convert floats to string
4271+
return valueOf(CProver.doubleToFloat(d));
42714272
// return Double.toString(d);
42724273
}
42734274

src/main/java/java/lang/StringBuffer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ public synchronized StringBuffer append(float f) {
576576
// toStringCache = null;
577577
// super.append(f);
578578
// return this;
579-
return CProver.nondetWithoutNullForNotModelled();
579+
return append(String.valueOf(f));
580580
}
581581

582582
/**
@@ -589,7 +589,7 @@ public synchronized StringBuffer append(double d) {
589589
// toStringCache = null;
590590
// super.append(d);
591591
// return this;
592-
return CProver.nondetWithoutNullForNotModelled();
592+
return append(String.valueOf(d));
593593
}
594594

595595
/**

src/main/java/org/cprover/CProver.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,4 +322,27 @@ public static String classIdentifier(Object object)
322322
{
323323
return object.getClass().getCanonicalName();
324324
}
325+
326+
/**
327+
* This method converts a double to a float and adds assumes that the conversion
328+
* did not result any loss of precision. Calling this method is useful when we
329+
* need to call a certain complicated operation on double, but we only have it
330+
* implemented for floats.
331+
*
332+
* The method is a workaround for the current limitations of the string solver,
333+
* which is able to convert float to String but not double to String. Once this
334+
* limitation goes away, the method and its usages can be removed.
335+
*
336+
* The method itself has limitations:
337+
* * There are doubles that can't be converted to float and back without loss
338+
* of precision, so the assertion will sometimes be violated
339+
* * Even if the assertion is satisfied for numbers d and converted, these
340+
* might not have the same String representation.
341+
*/
342+
public static float doubleToFloat(double d)
343+
{
344+
float converted = nondetFloat();
345+
assert(d == (double) converted);
346+
return converted;
347+
}
325348
}

0 commit comments

Comments
 (0)