Skip to content

Commit 79d3380

Browse files
author
Vojtěch Forejt
authored
Merge pull request #23 from diffblue/forejtv/floats-to-string
Handle common floats to string operations in the model and not in the string solver
2 parents 42b32df + 24afc75 commit 79d3380

File tree

3 files changed

+29
-6
lines changed

3 files changed

+29
-6
lines changed

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4269,8 +4269,9 @@ public static String valueOf(float f) {
42694269
* actual program.
42704270
*/
42714271
public static String valueOf(double d) {
4272-
// DIFFBLUE MODEL LIBRARY This is treated internally in CBMC
4273-
return CProver.nondetWithoutNullForNotModelled();
4272+
// DIFFBLUE MODEL LIBRARY we cast the number down to float because
4273+
// the string solver only knows how to convert floats to string
4274+
return valueOf(CProver.doubleToFloat(d));
42744275
// return Double.toString(d);
42754276
}
42764277

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -531,11 +531,10 @@ public synchronized StringBuffer append(char c) {
531531
*/
532532
@Override
533533
public synchronized StringBuffer append(int i) {
534-
// DIFFBLUE MODEL LIBRARY this is replaced internally
535534
// toStringCache = null;
536535
// super.append(i);
537536
// return this;
538-
return CProver.nondetWithoutNullForNotModelled();
537+
return append(String.valueOf(i));
539538
}
540539

541540
/**
@@ -576,7 +575,7 @@ public synchronized StringBuffer append(float f) {
576575
// toStringCache = null;
577576
// super.append(f);
578577
// return this;
579-
return CProver.nondetWithoutNullForNotModelled();
578+
return append(String.valueOf(f));
580579
}
581580

582581
/**
@@ -589,7 +588,7 @@ public synchronized StringBuffer append(double d) {
589588
// toStringCache = null;
590589
// super.append(d);
591590
// return this;
592-
return CProver.nondetWithoutNullForNotModelled();
591+
return append(String.valueOf(d));
593592
}
594593

595594
/**

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)