From Wikipedia, the free encyclopedia
In mathematics and computing, Fibonacci coding is a universal code[citation needed] which encodes positive integers into binary code words. It is one example of representations of integers based on Fibonacci numbers. Each code word ends with «11» and contains no other instances of «11» before the end.
The Fibonacci code is closely related to the Zeckendorf representation, a positional numeral system that uses Zeckendorf’s theorem and has the property that no number has a representation with consecutive 1s. The Fibonacci code word for a particular integer is exactly the integer’s Zeckendorf representation with the order of its digits reversed and an additional «1» appended to the end.
Definition[edit]
For a number , if represent the digits of the code word representing then we have:
where F(i) is the ith Fibonacci number, and so F(i+2) is the ith distinct Fibonacci number starting with . The last bit is always an appended bit of 1 and does not carry place value.
It can be shown that such a coding is unique, and the only occurrence of «11» in any code word is at the end i.e. d(k−1) and d(k). The penultimate bit is the most significant bit and the first bit is the least significant bit. Also leading zeros cannot be omitted as they can in e.g. decimal numbers.
The first few Fibonacci codes are shown below, and also their so-called implied probability, the value for each number that has a minimum-size code in Fibonacci coding.
Symbol | Fibonacci representation | Fibonacci code word | Implied probability |
---|---|---|---|
1 | 11 | 1/4 | |
2 | 011 | 1/8 | |
3 | 0011 | 1/16 | |
4 | 1011 | 1/16 | |
5 | 00011 | 1/32 | |
6 | 10011 | 1/32 | |
7 | 01011 | 1/32 | |
8 | 000011 | 1/64 | |
9 | 100011 | 1/64 | |
10 | 010011 | 1/64 | |
11 | 001011 | 1/64 | |
12 | 101011 | 1/64 | |
13 | 0000011 | 1/128 | |
14 | 1000011 | 1/128 |
To encode an integer N:
- Find the largest Fibonacci number equal to or less than N; subtract this number from N, keeping track of the remainder.
- If the number subtracted was the ith Fibonacci number F(i), put a 1 in place i−2 in the code word (counting the left most digit as place 0).
- Repeat the previous steps, substituting the remainder for N, until a remainder of 0 is reached.
- Place an additional 1 after the rightmost digit in the code word.
To decode a code word, remove the final «1», assign the remaining the values 1,2,3,5,8,13… (the Fibonacci numbers) to the bits in the code word, and sum the values of the «1» bits.
Comparison with other universal codes[edit]
Fibonacci coding has a useful property that sometimes makes it attractive in comparison to other universal codes: it is an example of a self-synchronizing code, making it easier to recover data from a damaged stream. With most other universal codes, if a single bit is altered, none of the data that comes after it will be correctly read. With Fibonacci coding, on the other hand, a changed bit may cause one token to be read as two, or cause two tokens to be read incorrectly as one, but reading a «0» from the stream will stop the errors from propagating further. Since the only stream that has no «0» in it is a stream of «11» tokens, the total edit distance between a stream damaged by a single bit error and the original stream is at most three.
This approach—encoding using sequence of symbols, in which some patterns (like «11») are forbidden, can be freely generalized.[1]
Example[edit]
The following table shows that the number 65 is represented in Fibonacci coding as 0100100011, since 65 = 2 + 8 + 55. The first two Fibonacci numbers (0 and 1) are not used, and an additional 1 is always appended.
Generalizations[edit]
The Fibonacci encodings for the positive integers are binary strings that end with «11» and contain no other instances of «11». This can be generalized to binary strings that end with N consecutive 1’s and contain no other instances of N consecutive 1’s. For instance, for N = 3 the positive integers are encoded as 111, 0111, 00111, 10111, 000111, 100111, 010111, 110111, 0000111, 1000111, 0100111, …. In this case, the number of encodings as a function of string length is given by the sequence of Tribonacci numbers.
For general constraints defining which symbols are allowed after a given symbol, the maximal information rate can be obtained by first finding the optimal transition probabilities using maximal entropy random walk, then use entropy coder (with switched encoder with decoder) to encode a message as a sequence of symbols fulfilling the found optimal transition probabilities.
See also[edit]
- Golden ratio base
- NegaFibonacci coding
- Ostrowski numeration
- Universal code
- Varicode, a practical application
- Zeckendorf’s theorem
- Maximal entropy random walk
References[edit]
- ^ Duda, Jarek (2007). «Optimal encoding on discrete lattice with translational invariant constrains using statistical algorithms». arXiv:0710.3861 [cs.IT].
- Allouche, Jean-Paul; Shallit, Jeffrey (2003). Automatic Sequences: Theory, Applications, Generalizations. Cambridge University Press. p. 105. ISBN 978-0-521-82332-6. Zbl 1086.11015.
- Fraenkel, Aviezri S.; Klein, Shmuel T. (1996). «Robust universal complete codes for transmission and compression». Discrete Applied Mathematics. 64 (1): 31–55. CiteSeerX 10.1.1.37.3064. doi:10.1016/0166-218X(93)00116-H. ISSN 0166-218X. Zbl 0874.94026.
Further reading[edit]
- Stakhov, A. P. (2009). The Mathematics of Harmony: From Euclid to Contemporary Mathematics and Computer Science. Singapore: World Scientific Publishing.
In this tutorial, we are going to learn how to convert a number to its wording (digit-wise). For instance, if the number is 12, the wordings will be “one-two”. A similar thing will be done for the rest of the inputs.
Code Implementation
We would be following a number of steps which are mentioned below:
Step 1: Creating a Global list for digit to word mapping
Create a global list containing wordings for each digit from 0 to 9. The list will contain elements mapped to the index as shown in the table below.
Index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
Wording / Value | zero | one | two | three | four | five | six | seven | eight | nine |
# Global Array storing word for each digit arr = ['zero','one','two','three','four','five','six','seven','eight','nine']
Step 2: Taking the input of the number and creating the main function
To take input of the number we will make use of input
function and then typecast it to integer and also we will create an empty function that will convert our number to words digit-wise.
# Global Array storing word for each digit arr = ['zero','one','two','three','four','five','six','seven','eight','nine'] def number_2_word(n): pass n = int(input()) print("Number Entered was : ", n) print("Converted to word it becomes: ",end="") print(number_2_word(n))
Step 3: Coding the Main Logic Inside the Function
For this code, we will be making use of Recursion. If you have very little or no knowledge about Recursion I would recommend you to check out the tutorial mentioned below:
Read more on Recursion: Recursion in Python
For every recursive call, we will check if my number became 0, if it did we would return an empty string otherwise we will keep adding the wordings for each digit with the help of the modulus function and divide the number by 10 to shrink the number and move to the next digit.
The code implementation is shown below and comments are added for your understanding.
# Global Array storing word for each digit arr = ['zero','one','two','three','four','five','six','seven','eight','nine'] def number_2_word(n): # If all the digits are encountered return blank string if(n==0): return "" else: # compute spelling for the last digit small_ans = arr[n%10] # keep computing for the previous digits and add the spelling for the last digit ans = number_2_word(int(n/10)) + small_ans + " " # Return the final answer return ans n = int(input()) print("Number Entered was : ", n) print("Converted to word it becomes: ",end="") print(number_2_word(n))
Outputs:
Number Entered was : 123 Converted to word it becomes: one two three
Number Entered was : 46830 Converted to word it becomes: four six eight three zero
Conclusion
So by end of this tutorial, we saw that the numbers can easily be converted to the wording (digit-wise) in a pretty easy and simple way by the use of Recursion.
Thank you for reading! Happy Learning! 😇
Here is another version from me with some unit tests.
Don’t use it with numbers larger than Number.MAX_SAFE_INTEGER
.
describe("English Numerals Converter", function () {
assertNumeral(0, "zero");
assertNumeral(1, "one");
assertNumeral(2, "two");
assertNumeral(3, "three");
assertNumeral(4, "four");
assertNumeral(5, "five");
assertNumeral(6, "six");
assertNumeral(7, "seven");
assertNumeral(8, "eight");
assertNumeral(9, "nine");
assertNumeral(10, "ten");
assertNumeral(11, "eleven");
assertNumeral(12, "twelve");
assertNumeral(13, "thirteen");
assertNumeral(14, "fourteen");
assertNumeral(15, "fifteen");
assertNumeral(16, "sixteen");
assertNumeral(17, "seventeen");
assertNumeral(18, "eighteen");
assertNumeral(19, "nineteen");
assertNumeral(20, "twenty");
assertNumeral(21, "twenty-one");
assertNumeral(22, "twenty-two");
assertNumeral(23, "twenty-three");
assertNumeral(30, "thirty");
assertNumeral(37, "thirty-seven");
assertNumeral(40, "forty");
assertNumeral(50, "fifty");
assertNumeral(60, "sixty");
assertNumeral(70, "seventy");
assertNumeral(80, "eighty");
assertNumeral(90, "ninety");
assertNumeral(99, "ninety-nine");
assertNumeral(100, "one hundred");
assertNumeral(101, "one hundred and one");
assertNumeral(102, "one hundred and two");
assertNumeral(110, "one hundred and ten");
assertNumeral(120, "one hundred and twenty");
assertNumeral(121, "one hundred and twenty-one");
assertNumeral(199, "one hundred and ninety-nine");
assertNumeral(200, "two hundred");
assertNumeral(999, "nine hundred and ninety-nine");
assertNumeral(1000, "one thousand");
assertNumeral(1001, "one thousand and one");
assertNumeral(1011, "one thousand and eleven");
assertNumeral(1111, "one thousand and one hundred and eleven");
assertNumeral(9999, "nine thousand and nine hundred and ninety-nine");
assertNumeral(10000, "ten thousand");
assertNumeral(20000, "twenty thousand");
assertNumeral(21000, "twenty-one thousand");
assertNumeral(90000, "ninety thousand");
assertNumeral(90001, "ninety thousand and one");
assertNumeral(90100, "ninety thousand and one hundred");
assertNumeral(90901, "ninety thousand and nine hundred and one");
assertNumeral(90991, "ninety thousand and nine hundred and ninety-one");
assertNumeral(90999, "ninety thousand and nine hundred and ninety-nine");
assertNumeral(91000, "ninety-one thousand");
assertNumeral(99999, "ninety-nine thousand and nine hundred and ninety-nine");
assertNumeral(100000, "one hundred thousand");
assertNumeral(999000, "nine hundred and ninety-nine thousand");
assertNumeral(1000000, "one million");
assertNumeral(10000000, "ten million");
assertNumeral(100000000, "one hundred million");
assertNumeral(1000000000, "one billion");
assertNumeral(1000000000000, "one trillion");
assertNumeral(1000000000000000, "one quadrillion");
assertNumeral(1000000000000000000, "one quintillion");
assertNumeral(1000000000000000000000, "one sextillion");
assertNumeral(-1, "minus one");
assertNumeral(-999, "minus nine hundred and ninety-nine");
function assertNumeral(number, numeral) {
it(number + " is " + numeral, function () {
expect(convert(number)).toBe(numeral);
});
}
});
function convert(n) {
let NUMERALS = [
{value: 1000000000000000000000, str: "sextillion"},
{value: 1000000000000000000, str: "quintillion"},
{value: 1000000000000000, str: "quadrillion"},
{value: 1000000000000, str: "trillion"},
{value: 1000000000, str: "billion"},
{value: 1000000, str: "million"},
{value: 1000, str: "thousand"},
{value: 100, str: "hundred"},
{value: 90, str: "ninety"},
{value: 80, str: "eighty"},
{value: 70, str: "seventy"},
{value: 60, str: "sixty"},
{value: 50, str: "fifty"},
{value: 40, str: "forty"},
{value: 30, str: "thirty"},
{value: 20, str: "twenty"},
{value: 19, str: "nineteen"},
{value: 18, str: "eighteen"},
{value: 17, str: "seventeen"},
{value: 16, str: "sixteen"},
{value: 15, str: "fifteen"},
{value: 14, str: "fourteen"},
{value: 13, str: "thirteen"},
{value: 12, str: "twelve"},
{value: 11, str: "eleven"},
{value: 10, str: "ten"},
{value: 9, str: "nine"},
{value: 8, str: "eight"},
{value: 7, str: "seven"},
{value: 6, str: "six"},
{value: 5, str: "five"},
{value: 4, str: "four"},
{value: 3, str: "three"},
{value: 2, str: "two"},
{value: 1, str: "one"}
];
if (n < 0) {
return "minus " + convert(-n);
} else if (n === 0) {
return "zero";
} else {
let result = "";
for (let numeral of NUMERALS) {
if (n >= numeral.value) {
if (n < 100) {
result += numeral.str;
n -= numeral.value;
if (n > 0) result += "-";
} else {
let times = Math.floor(n / numeral.value);
result += convert(times) + " " + numeral.str;
n -= numeral.value * times;
if (n > 0) result += " and ";
}
}
}
return result;
}
}
What if someone asks you a java program for writing numbers in words .The problem with the question is that we dont know how big the input number can be. So first question we need to ask what would be the range of the input. After getting the range , we can answer through algorithm or code of program.We provided two answers to this question as the countries like USA, UK uses million,billion,trillion terminology while Asian countries like India,Pakistan ,Srilanka uses lakh,crore,arab,kharab terminology.So lets find out the logic and java program for writing numbers in words.
Read Also : Length of String without using length() method
Convert String to int without using parseInt() method
There are two type of word formation depending upon the geography
Type 1 : in countries like United states of America(USA)
The format for writing numbers in words is like this
Unit,ten,hundred,thousand,million,billion,trillion,quadrillion,quintillion.
For example :
Input : 123456789
Output: One hundred twenty three million four hundred fifty six thousand seven hundred eighty nine
Logic :
After thousand number , there is a symmetry in special names like million,billion,trillion,quadrillion,quintillion.
The symmetry is if you multiply 1000 with thousand than we will get a million. If we multiply 1000 with million then we will get billion. If we multiply 1000 with billion then we get trillion.Similarly,1000 multiply trillion equals quadrillion. 1000 multiply quadrillion equals quintillion.This symmetry starts after we reach 1000 number . So we will divide the program into two parts .
First part that is function convertLessThanOneThousand(int number) will convert any number smaller than 1000 into words.
Second part, starting from extreme-right of input number, we will use modulus operator by1000, to get the last three extreme right digits of the input number.Taking three digits at a time from right to left , we will scan the whole input number until it is fully converted into the word.
Java Code for writing Numbers in Words :
public class NumberToWord
{ private static final String[] specialNames = { "", " thousand", " million", " billion", " trillion", " quadrillion", " quintillion" }; private static final String[] tensNames = { "", " ten", " twenty", " thirty", " forty", " fifty", " sixty", " seventy", " eighty", " ninety" }; private static final String[] numNames = { "", " one", " two", " three", " four", " five", " six", " seven", " eight", " nine", " ten", " eleven", " twelve", " thirteen", " fourteen", " fifteen", " sixteen", " seventeen", " eighteen", " nineteen" }; private String convertLessThanOneThousand(int number) { String current; if (number % 100 < 20){ current = numNames[number % 100]; number /= 100; } else { current = numNames[number % 10]; number /= 10; current = tensNames[number % 10] + current; number /= 10; } if (number == 0) return current; return numNames[number] + " hundred" + current; } public String convert(int number) { if (number == 0) { return "zero"; } String prefix = ""; if (number < 0) { number = -number; prefix = "negative"; } String current = ""; int place = 0; do { int n = number % 1000; if (n != 0){ String s = convertLessThanOneThousand(n); current = s + specialNames[place] + current; } place++; number /= 1000; } while (number > 0); return (prefix + current).trim(); } public static void main(String[] args) { NumberToWord obj = new NumberToWord(); System.out.println("*** " + obj.convert(123456789)); System.out.println("*** " + obj.convert(-55)); } }
one hundred twenty three million four hundred fifty six thousand seven hundred
eighty nine negative fifty five
Read Also : How to generate Random Number in Java
Top 15 must prepare Behavioral Interview Questions
Type 2 : in Asian countries like India, Pakistan, Srilanka
The format for writing numbers in words is like this
Unit,ten,hundred,thousand,lakh,crore,arab,kharab
Input : 123456789
Output: Twelve crore thirty four lakhs fifty six thousand seven hundred eighty nine
Logic :
In this number to word conversion , there is hundred pattern instead of thousand pattern mentioned above.
So, after reaching thousand , the pattern is 100 multiply thousand is lakh. 100 multiply lakh is crore . 100 multiply crore is arab. 100 multiply arab is kharab and so on. You can solve this question by above method also.
Java Code for writing Numbers in Words :
import java.util.*;
public class NumberToWord
{ private static String input; private static int num; private static String[] units=
{"", " One", " Two", " Three", " Four", " Five", " Six", " Seven", " Eight", " Nine" }; private static String[] teen= {" Ten", " Eleven", " Twelve", " Thirteen", " Fourteen", " Fifteen", " Sixteen", " Seventeen", " Eighteen", " Nineteen" }; private static String[] tens= { " Twenty", " Thirty", " Forty", " Fifty", " Sixty", " Seventy", " Eighty", " Ninety" }; private static String[] maxs= {"", "", " Hundred", " Thousand", " Lakh", " Crore" };
public String convertNumberToWords(int n) { input=numToString(n);
String converted="";
int pos=1;
boolean hun=false; while(input.length()> 0) { if(pos==1) // TENS AND UNIT POSITION { if(input.length()>= 2) // TWO DIGIT NUMBERS {
String temp=input.substring(input.length()-2,input.length()); input=input.substring(0,input.length()-2); converted+=digits(temp); } else if(input.length()==1) // 1 DIGIT NUMBER { converted+=digits(input);
input=""; } pos++; } else if(pos==2) // HUNDRED POSITION {
String temp=input.substring(input.length()-1,input.length()); input=input.substring(0,input.length()-1); if(converted.length()> 0&&digits(temp)!="") { converted=(digits(temp)+maxs[pos]+" and")+converted;
hun=true; } else { if (digits(temp)==""); else converted=(digits(temp)+maxs[pos])+converted;hun=true; } pos++; } else if(pos > 2) // REMAINING NUMBERS PAIRED BY TWO { if(input.length()>= 2) // EXTRACT 2 DIGITS {
String temp=input.substring(input.length()-2,input.length()); input=input.substring(0,input.length()-2); if(!hun&&converted.length()> 0) converted=digits(temp)+maxs[pos]+" and"+converted; else { if(digits(temp)=="") ; else converted=digits(temp)+maxs[pos]+converted; } } else if(input.length()==1) // EXTRACT 1 DIGIT {
if(!hun&&converted.length()> 0) converted=digits(input)+maxs[pos]+" and"+converted; else { if(digits(input)=="") ; else converted=digits(input)+maxs[pos]+converted; input=""; } } pos++; } } return converted; } private String digits(String temp) // TO RETURN SELECTED NUMBERS IN WORDS { String converted=""; for(int i=temp.length()-1;i >= 0;i--) { int ch=temp.charAt(i)-48; if(i==0&&ch>1 && temp.length()> 1) converted=tens[ch-2]+converted; // IF TENS DIGIT STARTS WITH 2 OR MORE IT FALLS UNDER TENS else if(i==0&&ch==1&&temp.length()==2) // IF TENS DIGIT STARTS WITH 1 IT FALLS UNDER TEENS { int sum=0; for(int j=0;j < 2;j++) sum=(sum*10)+(temp.charAt(j)-48); return teen[sum-10]; } else { if(ch > 0) converted=units[ch]+converted; } // IF SINGLE DIGIT PROVIDED } return converted; } private String numToString(int x) // CONVERT THE NUMBER TO STRING { String num=""; while(x!=0) { num=((char)((x%10)+48))+num; x/=10; } return num; } private void inputNumber() { Scanner in=new Scanner(System.in); try
{
System.out.print("Please enter number to Convert into Words : "); num=in.nextInt();
}
catch(Exception e)
{
System.out.println("Number should be Less than 1 Arab ");
System.exit(1);
} } public static void main(String[] args) { NumberToWord obj=new NumberToWord(); obj.inputNumber();
System.out.println("input in Words : "+obj.convertNumberToWords(num)); } }
Please mention in the comments in case you have any other simple way or any doubts regarding code .
Java program to convert numbers to words
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.text.NumberFormat; | |
public class NumberToWordsConverter { | |
public static final String[] units = { «», «One», «Two», «Three», «Four», | |
«Five», «Six», «Seven», «Eight», «Nine», «Ten», «Eleven», «Twelve», | |
«Thirteen», «Fourteen», «Fifteen», «Sixteen», «Seventeen», | |
«Eighteen», «Nineteen» }; | |
public static final String[] tens = { | |
«», // 0 | |
«», // 1 | |
«Twenty», // 2 | |
«Thirty», // 3 | |
«Forty», // 4 | |
«Fifty», // 5 | |
«Sixty», // 6 | |
«Seventy», // 7 | |
«Eighty», // 8 | |
«Ninety» // 9 | |
}; | |
public static String convert(final int n) { | |
if (n < 0) { | |
return «Minus « + convert(-n); | |
} | |
if (n < 20) { | |
return units[n]; | |
} | |
if (n < 100) { | |
return tens[n / 10] + ((n % 10 != 0) ? » « : «») + units[n % 10]; | |
} | |
if (n < 1000) { | |
return units[n / 100] + » Hundred» + ((n % 100 != 0) ? » « : «») + convert(n % 100); | |
} | |
if (n < 100000) { | |
return convert(n / 1000) + » Thousand» + ((n % 10000 != 0) ? » « : «») + convert(n % 1000); | |
} | |
if (n < 10000000) { | |
return convert(n / 100000) + » Lakh» + ((n % 100000 != 0) ? » « : «») + convert(n % 100000); | |
} | |
return convert(n / 10000000) + » Crore» + ((n % 10000000 != 0) ? » « : «») + convert(n % 10000000); | |
} | |
public static void main(final String[] args) { | |
int n; | |
n = 5; | |
System.out.println(NumberFormat.getInstance().format(n) + «='» + convert(n) + «‘»); | |
n = 16; | |
System.out.println(NumberFormat.getInstance().format(n) + «='» + convert(n) + «‘»); | |
n = 50; | |
System.out.println(NumberFormat.getInstance().format(n) + «='» + convert(n) + «‘»); | |
n = 78; | |
System.out.println(NumberFormat.getInstance().format(n) + «='» + convert(n) + «‘»); | |
n = 456; | |
System.out.println(NumberFormat.getInstance().format(n) + «='» + convert(n) + «‘»); | |
n = 1000; | |
System.out.println(NumberFormat.getInstance().format(n) + «='» + convert(n) + «‘»); | |
n = 99999; | |
System.out.println(NumberFormat.getInstance().format(n) + «='» + convert(n) + «‘»); | |
n = 199099; | |
System.out.println(NumberFormat.getInstance().format(n) + «='» + convert(n) + «‘»); | |
n = 10005000; | |
System.out.println(NumberFormat.getInstance().format(n) + «='» + convert(n) + «‘»); | |
} | |
} |