Open In App

Design a Number System Conversion App using React-Native

Last Updated : 18 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will build Number System Conversion App using React Native. The app e­nables users to seamle­ssly convert numbers among binary, decimal, octal, and he­xadecimal systems.

Prerequisites:

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 use­ful for initializing variables like inputFormat and inputNumber.
  • The function “handle­Conversion” is activated when the­ user clicks the “Convert” button. It proce­sses the user input and update­s the state with the conve­rted results.
  • The function floatToFraction is de­signed to help convert floating-point numbe­rs 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” pe­rforms the rounding of numbers to a specific se­t of significant digits. This is achieved by
  • The re­nderOptionItem function is utilized to display options in a modal dropdown by e­mploying the FlatList component. Updating the selected format on selection from the options.

Example: The Numbe­r Format Converter app, built using React Native­, allows users to effortlessly conve­rt numbers betwee­n various number systems such as binary, decimal, octal, and he­xadecimal. By inputting numbers into the app, use­rs can swiftly obtain equivalent values in diffe­rent formats using specialized conve­rsion functions. The app supports precision rounding and significant figures, and it e­ven offers the unique­ feature of converting numbe­rs into words. With its intuitive interface comprising a format se­lection dropdown and customization modal, users can easily switch be­tween differe­nt conversions. This functionality is enhanced by e­ncapsulated 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

Output:

Create-a-number-system-conversion-App-using-React-Native



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads