ChatGPT Writes Decent Code For Binary to Decimal Conversion

OK, enough just playing around with ChatGPT; let’s see if it can write some code:

Rick tells ChatGPT ‘Write Kotlin code to convert a binary number represented as a string to base 10’ and ChatGPT answers
Part two of Chat GPT's answer


(The line that got cut off in the screenshot of the second solution is

decimal += (binaryArray[i] - '0') * Math.pow(2.0, (binaryArray.size - 1 - i).toDouble()).toInt()

)

My first observation is that it was smart enough to know that by base 10 I meant decimal, and even named the function binaryToDecimal() as I would have.

The first solution is more clever then I was expecting; it uses the built-in function parseInt() to do the conversion directly. It compiles and runs successfully.

The second solution is along the lines of what I was expecting, although it computes the nonnegative powers of two instead of the more efficient “nested” multiplication by two as I do in function bin2dec_i(). It compiles and runs successfully, although it did have one warning from the IDE about the Math.pow() function: “Should be replaced with Kotlin function. Replace with ‘pow’ function”. I replaced “Math.pow(2.0,…” with “2.0.pow(…” and it got rid of the warning.

I was hoping that it might have generated code to handle arbitrary length integers, like my converters and calculators. I guess I’ll have to be more specific.

Arbitrary Length Integers

Rick tells ChatGPT ‘Write Kotlin code to convert an arbitrary precision binary number represented as a string to base 10’ and ChatGPT answers
Part two of Chat GPT's answer

(The line that got cut off in the screenshot of the second solution is

decimal = decimal.add(bit.multiply(BigInteger.valueOf(2).pow(binaryArray.size - 1 - i)))

)

It decided to use BigInteger, which is what I would have done.

The first solution compiles and runs successfully. It takes the “shortcut” of using BigInteger itself to convert integers to different bases directly.

The second solution does not compile. The compiler complains about valueOf(): “None of the following functions can be called with the arguments supplied.”. But a simple fix — appending .toLong() to (binaryArray[i] – ‘0’) — allowed it to compile and run successfully. It still has the same inefficiencies as the limited-precision solution above though.

Stylistically, it did not use operators for the BigInteger functions to make the code easier to read, like this:

decimal += bit * BigInteger.valueOf(2).pow(binaryArray.size - 1 - i)

When I set out with my query I was really hoping that it would generate code to handle any arbitrary length number, integer or floating-point; let’s add that to the request.

Arbitrary Length Floating-Point

Rick tells ChatGPT ‘Write Kotlin code to convert an arbitrary precision binary floating-point number represented as a string to base 10’ and ChatGPT answers
Part two of Chat GPT's answer

This solution does not compile. (And also has the same warning as above about Math.pow().) Even after fixing the small compiler error (changing “val decimal” to “var decimal”) the code works incorrectly. For the sample test code, it prints 1101.625. It incorrectly converts the integer part, treating it as decimal.

A simple additional fix that gets the sample test running correctly is to add import java.math.BigInteger and to replace

var decimal = BigDecimal(parts[0], MathContext.UNLIMITED)

with

var decimal = BigInteger(parts[0], 2).toBigDecimal()

which is a trick it used in another solution.

But the code still has an error, when the input has no integer part; for example, “.101”. This causes the runtime exception “Zero length BigInteger”. (With the original line that has BigDecimal, the runtime exception is “Index 0 out of bounds for length 0”.)

A simple fix for this is to replace the modified line with this further modified line:

var decimal = (if (parts[0].isEmpty()) BigInteger.ZERO else BigInteger(parts[0], 2)).toBigDecimal()

I tested the new version on this number:

 11101011100010101001000110101111010101011111101111111101011010111011.1110101011010001001001101010101010101010101010101010101011111010101010001011101010101

which gave this correct output, as confirmed by my binary to decimal converter:

 
271560613247152281275.9172538916269938194405650664083933868757033715246596017323099658824503421783447265625


There is one additional problem though. “Math.pow(0.5, i + 1.0)” will produce an incorrect result for binary fractional values that are 1074 bits or more. The smallest negative power of two representable in double-precision binary floating-point is 2-1074. Starting at i = 1074, which means when it computes 2-1075, the power will be 0, due to underflow.

The final fix is to use the BigInteger pow() function. In keeping with the original style of ChatGPT’s solution, and making the minimum change possible, I replaced

fraction += BigDecimal(bit * Math.pow(0.5, i + 1.0))

with

fraction += bit.toBigDecimal() * BigDecimal.ONE.divide(BigInteger.TWO.pow(i + 1).toBigDecimal())

I tested this with fractional values longer than 1074 bits.

Finally, I was expecting it to use BigIntegers with scaling, not BigDecimal, which is overkill. And it computes the negative powers of two instead of the more efficient “nested” division by two as I do in function bin2dec_f().

Conclusion

I’m not sure what to make of ChatGPT’s coding ability since I only asked it to code a short, well-known algorithm. But for this case I’d say its results are a great starting point, and is easier than searching the Web. On the other hand, searching could open your eyes to other solutions, and to the errors I pointed out.

It’s interesting that ChatGPT wrote decent Kotlin, given that it’s a relatively new language, and considering ChatGPT’s training data is only through 2021. I was also impressed that it printed the code in dark mode, which seems to be what developers prefer.

I wonder: if ChatGPT learned to code by reading others’ code, what happens when it learns from its own code? This sounds like one giant feedback loop converging to incorrect answers. (This is a bigger issue, applying to everything it learns, not just code.)

Addendum: Feb 15, 2023

I published this article yesterday and asked ChatGPT about it today:

Rick asks ChatGPT ‘What do you think of the article ChatGPT Writes Decent Code For Binary to Decimal Conversion?’ and ChatGPT answers

I’m really starting to question what it thinks it knows.

Except for a few individual lines, the code is in screenshots. Is it reading images?

A few things in its response that stick out:

  • “appears to be implemented correctly” (not quite)
  • “bitwise operators” (not using them)
  • “Python” (it’s Kotlin)
  • “input validation” (sure, good suggestion, but that’s the code you gave me)
Dingbat

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

(Cookies must be enabled to leave a comment...it reduces spam.)

Copyright © 2008-2024 Exploring Binary

Privacy policy

Powered by WordPress

css.php