React实现的数字格式转换器
在本文中,我们将创建一个数字格式转换器,为用户提供了各种功能,如十进制、二进制、八进制和十六进制之间的转换。使用函数式组件和状态管理,这个程序使用户能够输入一个数字并执行一系列的计算和转换。它展示了整数有效数字和小数位数四舍五入的功能,还包括单词表示法。这个程序使用JSX实现,可以帮助我们接收输入值并显示不同功能的输出值。
让我们看看我们最终项目的样子:
使用的技术/先决条件:
- ReactJS
- CSS
- JSX
- React中的功能组件
方法/功能:
利用ReactJS功能组件和状态管理创建一个交互式的基于网络的数字格式转换器。根据用户输入,采用一系列数学算法进行转换、四舍五入和有效位数计算。
- 输入和状态管理: 程序首先从用户那里接收一个数字输入,并使用React状态来管理各种数字值。
- 转换逻辑: 计算并显示输入数字的二进制、八进制、十进制和十六进制表示,以及整数部分和小数部分。
- 舍入和有效位: 用户可以将输入四舍五入到指定的小数位数,并选择在结果中想要的有效位数。
- 分数表示: 程序确定输入的分数部分,并在适当的情况下显示分子和分母。
- 以文字形式表示的整数部分: 为十进制的整数部分提供以文字形式表示的表示,使其成为进行数值转换和计算的综合工具。
创建应用程序的步骤:
步骤1: 使用以下命令设置React项目
npx create-react-app <<name of project>>
步骤2: 导航到项目文件夹使用
cd <<Name_of_project>>
步骤3: 在“components”文件夹中创建两个新文件,分别命名为Numberformat.js和Numberformat.css。
步骤4: 同时使用终端安装‘number-to-words’模块,以将整数转换为单词。打开一个新的终端窗口,输入以下命令:
npm install number-to-words
项目结构:
package.json中更新的依赖项将如下所示:
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"number-to-words": "^1.2.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}
示例 : 在相应的文件中编写以下代码
- App.js: 该文件导入Numberformat组件并将其导出。
- Numberformat.js: 该文件包含了Number format转换器的逻辑、转换技巧以及将一个数字从十进制格式转换到其他基数格式、舍入和有效数字,以及数字的语言表示方法。
- Numberformat.css: 该文件包含了Numberformat元素的设计。
// App.js
import './App.css';
import NumberFormat from './components/Numberformat.js';
function App() {
return (
<div className="App">
<NumberFormat/>
</div>
);
}
export default App;
// NumberFormat.js
import React, { useState } from 'react'
import './Numberformat.css';
import numberToWords from 'number-to-words';
export default function Numberformat() {
const [inputFormat, setInputFormat] = useState('decimal');
const [inputNumber, setInputNumber] = useState('');
const [decimal, setDecimal] = useState('');
const [binary, setBinary] = useState('');
const [octal, setOctal] = useState('');
const [hexadecimal, setHexadecimal] = useState('');
const [rounddigit, setRoundDigit] = useState('');
const [rounddigitindex, setRoundDigitindex] = useState('2');
const [significantno, setSignificantno] = useState('');
const [significantnoindex, setSignificantnoindex] = useState('2');
const [integer, setInteger] = useState(' ');
const [numerator, setNumerator] = useState('0');
const [denominator, setDenominator] = useState('0');
const [inword, setInword] = useState('');
const handleConversion = () => {
let decimalValue;
switch (inputFormat) {
case 'binary':
decimalValue = parseInt(inputNumber, 2);
break;
case 'octal':
decimalValue = parseInt(inputNumber, 8);
break;
case 'hexadecimal':
decimalValue = parseInt(inputNumber, 16);
break;
default:
decimalValue = parseInt(inputNumber, 10);
}
if (inputFormat !== 'decimal') setDecimal(decimalValue);
// Finding Integer Number
setInteger(Math.floor(decimalValue));
// Finding the Binary Representation
setBinary((Math.floor(decimalValue)).toString(2));
// Finding the Octal Representation
setOctal((Math.floor(decimalValue)).toString(8));
// Finding the Hexadecimal Representation
setHexadecimal((Math.floor(decimalValue)).toString(16).toUpperCase());
// Setting the word for given integer
if(decimalValue <= 1000000000000000) setInword(numberToWords.toWords(decimalValue));
else setInword("Over Limit (Max-Limit : 1000000000000000");
// Setting the Rounded Number
if (inputFormat === 'decimal') setRoundDigit(roundToKthInteger(parseFloat(decimal, 10), parseInt(rounddigitindex, 10)));
else setRoundDigit(roundToKthInteger(parseFloat(decimalValue, 10), parseInt(rounddigitindex, 10)));
// Setting the numerator and denominator
if (inputFormat === 'decimal' && parseFloat(decimal, 10) - decimalValue !== 0) {
const result = floatToFraction(parseFloat(decimal, 10) - decimalValue);
setNumerator(result.numerator);
setDenominator(result.denominator);
} else {
setNumerator('0');
setDenominator('0');
}
// Setting the Significant Digits
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 numerator = 1;
let denominator = 1;
let error = number - numerator / denominator;
while (Math.abs(error) > tolerance) {
if (error > 0) numerator++;
else denominator++;
error = number - numerator / denominator;
}
return {
numerator: numerator,
denominator: denominator
};
}
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;
}
return (
<div className='application'>
<h1>Number Format Converter</h1>
<div className="section">
<div className="row">
<p>From</p>
<select value={inputFormat} onChange={(e) => setInputFormat(e.target.value)}>
<option value="binary">Binary</option>
<option value="decimal">Decimal</option>
<option value="octal">Octal</option>
<option value="hexadecimal">Hexadecimal</option>
</select>
</div>
<div className="row">
<p>Enter {inputFormat} Number</p>
<div>
<input
type={(inputFormat !== 'decimal') ? "text" : "number"}
value={inputNumber}
onChange={(e) => {
if (inputFormat === 'decimal') {
setDecimal(e.target.value);
setInputNumber(e.target.value)
} else {
setInputNumber(e.target.value);
}
}}
/>
<button onClick={handleConversion}>Convert</button>
</div>
</div>
<div className="row">
<p>Integer Number</p>
<input
type="number"
value={integer}
onChange={(e) => { }}
/>
</div>
<div className="row">
<p>Significant Number</p>
<div>
<input
type="number"
value={significantno}
onChange={(e) => { }}
/>
<select value={significantnoindex} onChange={(e) => {
setSignificantnoindex(e.target.value)
if (decimal !== '') setSignificantno(roundToSignificantDigits(parseFloat(decimal, 10), parseInt(e.target.value, 10)));
}}>
{[...Array(9).keys()].map((value) => (
<option key={value + 1} value={value + 1}>
{value + 1}
</option>
))}
</select>
</div>
</div>
<div className="row">
<p>Rounded Number</p>
<div>
<input
type="number"
value={rounddigit}
onChange={(e) => { }}
/>
<select value={rounddigitindex} onChange={(e) => {
setRoundDigitindex(e.target.value);
if (decimal !== '') setRoundDigit(roundToKthInteger(parseFloat(decimal), parseInt(e.target.value, 10)));
}}>
{[...Array(10).keys()].map((value) => (
<option key={value} value={value}>
{value}
</option>
))}
</select>
</div>
</div>
<div className="row">
<p>Fraction</p>
<div>
<input
type="number"
value={integer}
onChange={(e) => { }}
/>
<input
type="number"
value={numerator}
onChange={(e) => { }}
/>
<p> / </p>
<input
type="number"
value={denominator}
onChange={(e) => { }}
/>
</div>
</div>
<div className="row">
<p>{(inputFormat === 'binary') ? "Decimal" : "Binary"} Format(Base-{(inputFormat === 'binary') ? "10" : "2"}) of Integer {integer}</p>
<input
type="number"
value={(inputFormat === 'binary') ? decimal : binary}
onChange={(e) => { }}
/>
</div>
<div className="row">
<p>{(inputFormat === 'octal') ? "Decimal" : "Octal"} Format(Base-{(inputFormat === 'octal') ? "10" : "8"}) of Integer {integer}</p>
<input
type="number"
value={(inputFormat === 'octal') ? decimal : octal}
onChange={(e) => { }}
/>
</div>
<div className="row">
<p>{(inputFormat === 'hexadecimal') ? "Decimal" : "Hexadecimal"} Format(Base-{(inputFormat === 'hexadecimal') ? "10" : "16"}) of Integer {integer}</p>
<input
type="text"
value={(inputFormat === 'hexadecimal') ? decimal : hexadecimal}
onChange={(e) => { }}
/>
</div>
<div className="row">
<p>In Words of Integer {integer}</p>
<input
type="text"
value={inword}
onChange={(e) => { }}
/>
</div>
</div>
</div>
)
}
CSS
/* Numberformat.css */
body{
margin: 0;
padding: 0;
}
.application{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-bottom: 10px;
}
.application h1{
margin: 5px;
}
.section{
background-color: #f0eedc;
border: 1px solid #e0e0e0;
border-radius: 7px;
width: calc(100% - 55px);
max-width: 500px;
padding: 20px;
}
.row{
margin-bottom: 5px;
}
.row p{
margin: 0;
text-align: left;
padding: 5px 7px;
}
.row div{
display: flex;
justify-content: center;
align-items: center;
}
.row input{
width: calc(100% - 33px);
font-size: 1rem;
padding: 6px 10px;
font-weight: 400;
line-height: 1.5;
color: #495057;
outline: none;
background-color: #fff;
background-clip: padding-box;
border: 1px solid #ced4da;
border-radius: 0.25rem;
}
.row:first-child select{
display: block;
width: calc(100% - 10px);
padding: 9px;
border: 1px solid #ced4da;
border-radius: 0.25em;
margin: 0px 5px;
outline: none;
}
.row:nth-child(2) input{
width: calc(100% - 135px);
}
.row button{
font-size: 16px;
outline: none;
border: 1px solid #28a745;
padding: 9px 20px;
border-radius: 4px;
color: #fff;
cursor: pointer;
background-color: #28a745;
transition: background-color .15s ease-in-out;
margin-left: 5px;
}
.row button:hover{
background-color: #1f953a;
}
.row:nth-child(4) input{
width: calc(100% - 90px);
}
.row:nth-child(4) select{
padding: 9px;
width: 50px;
margin-left: 5px;
border-radius: 0.25em;
outline: none;
border: 1px solid #ced4da;
}
.row:nth-child(5) input{
width: calc(100% - 90px);
}
.row:nth-child(5) select{
padding: 9px;
width: 50px;
margin-left: 5px;
border-radius: 0.25em;
outline: none;
border: 1px solid #ced4da;
}
.row:nth-child(6) div{
width: calc(100% - 5px);
}
.row:nth-child(6) p{
width: 6%;
text-align: center;
}
.row:nth-child(6) input{
width: 17%;
}
.row:nth-child(6) input:first-child{
width: 60%;
margin-right: 5px;
margin-left: 5px;
}
运行应用的步骤:
1. 在终端中输入以下命令。
npm start
2. 打开网页浏览器并输入以下网址
http://localhost:3000/
输出: