Design a Number System Conversion App using React-Native
In this article, we will build Number System Conversion App using React Native. The app enables users to seamlessly convert numbers among binary, decimal, octal, and hexadecimal systems.
Prerequisites:
- Introduction to React Native
- React Native Components
- React Hooks
- Node.js and NPM
Steps to Create React Native Application
Step 1: Create a React Native Application
Create a new React Native project for NumberSystemConversionApp
npx create-expo-app NumberSystemConversionApp
Step 2: Change the directory to the project folder
cd NumberSystemConversionApp
Step 3: Install Required Packages
npm install number-to-words
Project Structure
package.json
{
"dependencies": {
"number-to-words": "*",
"@expo/vector-icons": "^13.0.0",
"react-native-paper": "4.9.2"
}
}
Approach:
- UseState is a React hook that allows managing state in functional components. It’s useful for initializing variables like inputFormat and inputNumber.
- The function “handleConversion” is activated when the user clicks the “Convert” button. It processes the user input and updates the state with the converted results.
- The function floatToFraction is designed to help convert floating-point numbers into fractions. It achieves this by identifying the fraction that
- roundToKthInteger: Rounds numbers to a specified decimal place, using a power of 10.
- The function “roundToSignificantDigits” performs the rounding of numbers to a specific set of significant digits. This is achieved by
- The renderOptionItem function is utilized to display options in a modal dropdown by employing the FlatList component. Updating the selected format on selection from the options.
Example: The Number Format Converter app, built using React Native, allows users to effortlessly convert numbers between various number systems such as binary, decimal, octal, and hexadecimal. By inputting numbers into the app, users can swiftly obtain equivalent values in different formats using specialized conversion functions. The app supports precision rounding and significant figures, and it even offers the unique feature of converting numbers into words. With its intuitive interface comprising a format selection dropdown and customization modal, users can easily switch between different conversions. This functionality is enhanced by encapsulated conversion functions that enable seamless switching.
Javascript
// App.js import React, { useState } from 'react' ; import { View, Text, TextInput, Button, StyleSheet, Modal, TouchableOpacity, FlatList, ScrollView, } from 'react-native' ; import numberToWords from 'number-to-words' ; import { styles } from "./styles" ; export default function Numberformat() { let [inputFormat, setInputFormat] = useState( 'decimal' ); let [inputNumber, setInputNumber] = useState( '' ); let [decimal, setDecimal] = useState( '' ); let [binary, setBinary] = useState( '' ); let [octal, setOctal] = useState( '' ); let [hexadecimal, setHexadecimal] = useState( '' ); let [rounddigit, setRoundDigit] = useState( '' ); let [rounddigitindex, setRoundDigitindex] = useState( '2' ); let [significantno, setSignificantno] = useState( '' ); let [significantnoindex, setSignificantnoindex] = useState( '2' ); let [integer, setInteger] = useState( '' ); let [numerator, setNumerator] = useState( '0' ); let [denominator, setDenominator] = useState( '0' ); let [inword, setInword] = useState( '' ); let [modalVisible, setModalVisible] = useState( false ); let [options] = useState([ { label: 'Binary' , value: 'binary' }, { label: 'Decimal' , value: 'decimal' }, { label: 'Octal' , value: 'octal' }, { label: 'Hexadecimal' , value: 'hexadecimal' }, ]); // Conversion functions object const conversionFunctions = { binary: (input) => parseInt(input, 2), octal: (input) => parseInt(input, 8), hexadecimal: (input) => parseInt(input, 16), decimal: (input) => parseInt(input, 10), }; const handleConversion = () => { const decimalValue = conversionFunctions[inputFormat](inputNumber); setDecimal(decimalValue); setInteger(Math.floor(decimalValue).toString()); setBinary(Math.floor(decimalValue).toString(2)); setOctal(Math.floor(decimalValue).toString(8)); setHexadecimal(Math.floor(decimalValue) .toString(16).toUpperCase()); if (decimalValue <= 1000000000000000) { setInword(numberToWords.toWords(decimalValue)); } else { setInword( "Over Limit (Max-Limit: 1000000000000000)" ); } setRoundDigit(roundToKthInteger( parseFloat(decimalValue, 10), parseInt(rounddigitindex, 10)) ); if (inputFormat === 'decimal' && parseFloat(decimal, 10) - decimalValue !== 0) { const result = floatToFraction( parseFloat(decimal, 10) - decimalValue); setNumerator(result.numerator.toString()); setDenominator(result.denominator.toString()); } else { setNumerator( '0' ); setDenominator( '0' ); } if (inputFormat === 'decimal' ) { setSignificantno(roundToSignificantDigits( parseFloat(decimal, 10), parseInt(significantnoindex, 10) )); } else { setSignificantno(roundToSignificantDigits( parseFloat(decimalValue, 10), parseInt(significantnoindex, 10) )); } }; function floatToFraction(number) { const tolerance = 0.000001; let numeratorvalue = 1; let denominatorvalue = 1; let error = number - numeratorvalue / denominatorvalue; while (Math.abs(error) > tolerance) { if (error > 0) numeratorvalue++; else denominatorvalue++; error = number - numeratorvalue / denominatorvalue; } return { numerator: numeratorvalue, denominator: denominatorvalue }; } function roundToKthInteger(number, k) { const multiplier = Math.pow(10, k); return Math.round(number * multiplier) / multiplier; } function roundToSignificantDigits(number, significantDigits) { if (significantDigits <= 0) return 0; const multiplier = Math.pow(10, significantDigits - Math.floor (Math.log10(Math.abs(number))) - 1); const roundedNumber = (Math.round(number * multiplier) / multiplier); return roundedNumber; } const renderOptionItem = ({ item }) => ( <TouchableOpacity style={styles.optionItem} onPress={() => { setInputFormat(item.value); setModalVisible( false ); }} > <Text style={styles.optionText}>{item.label}</Text> </TouchableOpacity> ); return ( <ScrollView> <View style={styles.container}> <Text style={styles.header}> Number Format Converter </Text> <TouchableOpacity style={styles.dropdownButton} onPress={() => setModalVisible( true )} > <Text>{inputFormat}</Text> </TouchableOpacity> <View style={styles.section}> <Text style={styles.label}> Enter {inputFormat} Number </Text> <View style={styles.inputContainer}> <TextInput style={styles.input} keyboardType={ (inputFormat !== 'decimal' ) ? "default" : "numeric" } value={inputNumber} onChangeText={(text) => { if (inputFormat === 'decimal' ) { setDecimal(text); setInputNumber(text); } else { setInputNumber(text); } }} /> <TouchableOpacity style={styles.btn} onPress={handleConversion} > <Text style={styles.btnText}>Convert</Text> </TouchableOpacity> </View> </View> { /* Display the conversion results here */ } <View style={styles.resultSection}> <Text style={styles.resultHeader}> Integer Number </Text> <Text style={styles.resultText}>{integer}</Text> </View> <View style={styles.resultSection}> <Text style={styles.resultHeader}> Binary Format (Base-2) of Integer {integer} </Text> <Text style={styles.resultText}>{binary}</Text> </View> <View style={styles.resultSection}> <Text style={styles.resultHeader}> Octal Format (Base-8) of Integer {integer} </Text> <Text style={styles.resultText}>{octal}</Text> </View> <View style={styles.resultSection}> <Text style={styles.resultHeader}> Hexadecimal Format (Base-16) of Integer {integer} </Text> <Text style={styles.resultText}>{hexadecimal}</Text> </View> <View style={styles.resultSection}> <Text style={styles.resultHeader}> In Words of Integer {integer} </Text> <Text style={styles.resultText}>{inword}</Text> </View> <View style={styles.resultSection}> <Text style={styles.resultHeader}>Rounded Number</Text> <Text style={styles.resultText}>{rounddigit}</Text> </View> <View style={styles.resultSection}> <Text style={styles.resultHeader}>Significant Number</Text> <Text style={styles.resultText}>{significantno}</Text> </View> { /* Modal for Options */ } <Modal animationType= "slide" transparent={ true } visible={modalVisible} onRequestClose={() => setModalVisible( false )} > <View style={styles.modalContainer}> <View style={styles.modalContent}> <FlatList data={options} renderItem={renderOptionItem} keyExtractor={(item) => item.value} /> </View> </View> </Modal> </View> </ScrollView> ); } |
CSS
//styles.js import { StyleSheet } from 'react-native' ; const styles = StyleSheet.create({ container: { flex: 1 , padding : 20 , alignItems: 'center' , backgroundColor: '#f7f7f7' , }, header: { fontSize: 24 , marginBottom: 20 , textAlign: "center" , color : "green" , fontWeight: "bold" , margin : 20 , }, dropdownButton: { borderWidth: 1 , borderColor: '#ced4da' , borderRadius: 4 , padding : 8 , width : '100%' , marginBottom: 20 , alignItems: 'center' , backgroundColor: '#fff' , }, section: { backgroundColor: '#fff' , borderWidth: 1 , borderRadius: 7 , width : '100%' , maxWidth: 500 , padding : 20 , marginBottom: 20 , }, inputContainer: { flexDirection: 'row' , alignItems: 'center' , }, input: { flex: 1 , fontSize: 16 , padding : 8 , borderWidth: 1 , borderColor: '#ced4da' , borderRadius: 4 , marginRight: 5 , backgroundColor: '#fff' , }, label: { fontSize: 15 , color : '#000' , fontWeight: "bold" , }, btn: { fontSize: 16 , padding : 8 , borderRadius: 10 , backgroundColor: '#28a745' , marginLeft: 5 , shadowOffset: { width : 0 , height : 6 }, shadowColor: 'grey' , shadowOpacity: 0.5 , shadowRadius: 15 , }, btnText: { fontSize: 16 , padding : 8 , color : '#fff' , fontWeight: "bold" , }, resultSection: { marginBottom: 20 , backgroundColor: '#fff' , borderWidth: 1 , borderRadius: 7 , padding : 20 , width : '100%' , maxWidth: 500 , shadowOffset: { width : -2 , height : 4 }, shadowColor: 'grey' , shadowOpacity: 1 , shadowRadius: 13 , }, resultHeader: { fontSize: 18 , marginBottom: 10 , }, resultText: { fontSize: 19 , color : "red" , fontWeight: "bold" , }, modalContainer: { flex: 1 , justifyContent: 'center' , alignItems: 'center' , backgroundColor: 'rgba(0, 0, 0, 0.5)' , }, modalContent: { backgroundColor: 'white' , borderRadius: 10 , padding : 20 , width : '80%' , maxHeight: '80%' , }, optionItem: { padding : 10 , borderBottomWidth: 1 , borderBottomColor: '#ced4da' , }, optionText: { fontSize: 16 , }, }); export { styles } |
Steps to Run:
To run react native application use the following command:
npx expo start
- To run on Android:
npx react-native run-android
- To run on iOS:
npx react-native run-ios