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

(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

(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

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:

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)