📜 ⬆️ ⬇️

Brainfuck - output in decimal format

As the first task for implementation on the brainfuck, I decided to take a seemingly simple exercise - to output a 4-byte number written on a tape in decimal format. The problem turned out to be interesting, especially if we consider that duplicating the code (and using that the number is 4-byte) I wanted as little as possible, and using cycles more.

It was immediately obvious that there are two different approaches - either try to divide the original number with the remainder by 10, and compose the figures from the resulting residues, or form a decimal number, multiplying it by 2 and adding one if necessary. Having played with the second option, and having found out that bits arrive not in that order in which it is necessary, I returned to the first option.


')
There were two problems - the first: to avoid the occurrence of leading zeros, the second: to write division with the remainder of the “long” number by 10. The second task obviously comes down to dividing a two-byte number less than 2560 ... But let's go straight to the program.

First enter. In principle, it is not needed (by condition, the number is already written on the tape), but it’s necessary to somehow debug

,>,>,>, <<<

To be able to use the loop on the source data, we introduce additional markup.

<+>
>>> [- >>> + <<<] <
[- >> + <<] <
[-> + <]
+ >> + >> +

Between the bytes of the original number and to the left of the left byte are one. The carriage is on the rightmost unit (between two low bytes). We start the main loop. From this point on, the length of the source data is not used anywhere.

First we find the beginning of the number.

[[<<] >>

Now we will shift each digit 4 cells to the left, and in the vacated space divide the number made up of the previous balance and the new digit by 10:

[-> [- <<<< + >>>>] <<<<<
[- >> +> + <<<] >> +
[- <[- >> +> ++++++++++ <[-> -> + <<] +> [- <[-]>] <[- >> [-] <<< << + >>>] >> [- << + >>] <<<<] ->]

Here we use the fact that (a * 256 + b) / 10 = ((a * 255 + b) + a) / 10, and that a <10.

After the quotient and the remainder are found, it is necessary to check whether the leading zero has turned out. If it turned out, then we do not put the label “1” between the found and the next bytes.

<+ <[-> +> + <<]
>> [- << [-] + >>] <<<< [- >> [-] + >> + <<<<] >>>>
[- <<<< + >>>>]> [- <+>] >>>]

When the number is over, the last residue found is a new figure. We attribute it to the output line.

<++++++ [-> ++++++++ <] <<< [- >>>> + <<<<]

and shift the digits of the quotient found at this step by 3 bytes to the right (so that they are at the correct distance from the output line)

<< [-> [- >>> + <<<] >> + <<<<<] >>>>>]

If it turns out that there is no private thing, the cycle is finished - and you can output the string

> [.>] +++++++++++++ .---.

That's all.

It turned out somehow cumbersome - probably, I still do not see many opportunities.

Maybe the doubling option would be better - but for him the original numbers would not have to be divided, and multiplied by 2, and to work with the carry bit. I'll have to try. But this option will work only when the number of “byte” states is a power of two (in the above code this fact is not used, the program will work with any number of states greater than 10).

Source: https://habr.com/ru/post/113252/


All Articles