如何解决浮点数计算
How to solve floating numbers calculation
在我的应用程序中,有两个浮点数之间的计算。尽管应用了 toFixed(2)
方法,但我得到了奇怪的数字,例如 1.0300000000009。我知道这个问题是关于二进制和十进制数以及计算机如何处理它的,但我不知道如何解决它。我将不胜感激任何帮助,或为我指明正确方向的任何事情。
检查解决方案的工作代码示例:https://codesandbox.io/s/black-sound-rseqb
<template>
<div>
<table>
<tr>
<th>A</th>
<td class="sign">{{ this.randomSign.A }}</td>
<td>{{ initialValueA }}</td>
<td v-show="this.randomSign.A == '+'">⬆</td>
<td v-show="this.randomSign.A == '-'">⬇</td>
</tr>
</table>
<button @click="toggleInterval('A')">
<span v-show="this.startStop.A">Stop</span>
<span v-show="!this.startStop.A">Start</span>
</button>
<table>
<tr>
<th>B</th>
<td class="sign">{{ this.randomSign.B }}</td>
<td>{{ initialValueB }}</td>
<td v-show="this.randomSign.B == '+'">⬆</td>
<td v-show="this.randomSign.B == '-'">⬇</td>
</tr>
</table>
<button @click="toggleInterval('B')">
<span v-show="this.startStop.B">Stop</span>
<span v-show="!this.startStop.B">Start</span>
</button>
</div>
</template>
<script>
export default {
name: 'TableFields',
props: {
changesA: {
type: Array,
required: false
},
changesB: {
type: Array,
required: false
}
},
data () {
return {
timerA: undefined,
timerB: undefined,
fields: ['A', 'B'],
startStop: {
A: true,
B: true
},
initialValueA: 3,
initialValueB: 3,
randomNumbersArray: [],
randomSign: {
A: '+',
B: '+'
},
signsArray: ['+', '-'],
localChanges: {
A: [],
B: []
}
}
},
computed: {},
methods: {
firstObjects () { // creates first objects A, B
for (let i = 0; i < this.fields.length; i++) {
const date = new Date()
const obj = {}
obj.field = this.fields[i]
obj.value = Number((Math.random() * 1 + 1).toFixed(2))
obj.time = date.toLocaleTimeString()
this.changesA.push(obj[i])
this.changesB.push(obj[i])
this.$emit('update:changesA', this.localChanges.A)
this.$emit('update:changesB', this.localChanges.B)
}
},
replaceNumbersArray () { // replace random A, B numbers at time interval
const numberA = Number((Math.random() * 1 + 1).toFixed(2)) // first number A
const numberB = Number((Math.random() * 1 + 1).toFixed(2)) // first number B
this.randomNumbersArray.splice(0, 2, numberA, numberB)
},
toggleInterval (field) { // button toggle
if (field === 'A') {
this.startStop.A = !this.startStop.A
if (this.startStop.A) {
this.timerA = setInterval(() => { this.calculations('A') }, 2000)
} else {
clearInterval(this.timerA)
}
}
if (field === 'B') {
this.startStop.B = !this.startStop.B
if (this.startStop.B) {
this.timerB = setInterval(() => { this.calculations('B') }, 2000)
} else {
clearInterval(this.timerB)
}
}
},
calculations (field) {
if (field === 'A') {
this.randomSign.A = this.signsArray[
Math.floor(Math.random() * this.signsArray.length)
]
this.randomSign.A === '+'
? (this.initialValueA += this.randomNumbersArray[0])
: (this.initialValueA -= this.randomNumbersArray[0])
const date = new Date()
const newChange = {}
newChange.field = 'A'
newChange.value = this.randomNumbersArray[0]
newChange.time = date.toLocaleTimeString()
this.changesA.push(newChange)
this.$emit('update:changesA', this.localChanges.A)
}
if (field === 'B') {
this.randomSign.B = this.signsArray[
Math.floor(Math.random() * this.signsArray.length)
]
this.randomSign.B === '+'
? (this.initialValueB += this.randomNumbersArray[1])
: (this.initialValueB -= this.randomNumbersArray[1])
const date = new Date()
const newChange = {}
newChange.field = 'B'
newChange.value = this.randomNumbersArray[1]
newChange.time = date.toLocaleTimeString()
this.changesB.push(newChange)
this.$emit('update:changesB', this.localChanges.B)
}
}
},
mounted () {
this.firstObjects()
setInterval(this.replaceNumbersArray, 2000)
this.initialValueA = this.$root.initialValueA || 3
this.timerA = setInterval(() => {
this.calculations('A')
}, 2000)
this.initialValueB = this.$root.initialValueB || 3
this.timerB = setInterval(() => {
this.calculations('B')
}, 2000)
},
beforeDestroy () {
this.$root.initialValueA = this.initialValueA
this.$root.initialValueB = this.initialValueB
clearInterval(this.timerA)
clearInterval(this.timerB)
}
}
</script>
<style lang="scss" scoped>
button {
margin-bottom: 15px;
&:last-child {
margin-bottom: 0;
}
}
.sign {
width: 12px;
text-align: center;
}
button {
border: 1px solid transparent;
border-radius: 0;
background-color: #42b983;
color: #ffffff;
margin-top: 7px;
padding: 5px 10px;
&:hover {
opacity: 0.9;
cursor: pointer;
}
}
</style>
例如:
function accAdd(arg1, arg2) {
var r1, r2, m;
try {
r1 = arg1.toString().split(".")[1].length;
} catch(e) {
r1 = 0;
}
try {
r2 = arg2.toString().split(".")[1].length;
}catch(e){
r2 = 0;
}
m = Math.pow(10, Math.max(r1, r2));
return(arg1 * m + arg2 * m) / m;
}
计算时,保留数字。显示的时候,把它们变成想要的格式。
这个需要补充:
computed: {
valueA () {
return this.initialValueA.toFixed(2)
},
valueB () {
return this.initialValueB.toFixed(2)
}
}
然后像这样调用模板中的函数:
<td>{{ valueA }}</td>
和 <td>{{ valueB }}</td>
而不是
<td>{{ initialValueA }}</td>
和 <td>{{ initialValueA }}</td>
所有致谢来自 discord 的“kusu”。
在我的应用程序中,有两个浮点数之间的计算。尽管应用了 toFixed(2)
方法,但我得到了奇怪的数字,例如 1.0300000000009。我知道这个问题是关于二进制和十进制数以及计算机如何处理它的,但我不知道如何解决它。我将不胜感激任何帮助,或为我指明正确方向的任何事情。
检查解决方案的工作代码示例:https://codesandbox.io/s/black-sound-rseqb
<template>
<div>
<table>
<tr>
<th>A</th>
<td class="sign">{{ this.randomSign.A }}</td>
<td>{{ initialValueA }}</td>
<td v-show="this.randomSign.A == '+'">⬆</td>
<td v-show="this.randomSign.A == '-'">⬇</td>
</tr>
</table>
<button @click="toggleInterval('A')">
<span v-show="this.startStop.A">Stop</span>
<span v-show="!this.startStop.A">Start</span>
</button>
<table>
<tr>
<th>B</th>
<td class="sign">{{ this.randomSign.B }}</td>
<td>{{ initialValueB }}</td>
<td v-show="this.randomSign.B == '+'">⬆</td>
<td v-show="this.randomSign.B == '-'">⬇</td>
</tr>
</table>
<button @click="toggleInterval('B')">
<span v-show="this.startStop.B">Stop</span>
<span v-show="!this.startStop.B">Start</span>
</button>
</div>
</template>
<script>
export default {
name: 'TableFields',
props: {
changesA: {
type: Array,
required: false
},
changesB: {
type: Array,
required: false
}
},
data () {
return {
timerA: undefined,
timerB: undefined,
fields: ['A', 'B'],
startStop: {
A: true,
B: true
},
initialValueA: 3,
initialValueB: 3,
randomNumbersArray: [],
randomSign: {
A: '+',
B: '+'
},
signsArray: ['+', '-'],
localChanges: {
A: [],
B: []
}
}
},
computed: {},
methods: {
firstObjects () { // creates first objects A, B
for (let i = 0; i < this.fields.length; i++) {
const date = new Date()
const obj = {}
obj.field = this.fields[i]
obj.value = Number((Math.random() * 1 + 1).toFixed(2))
obj.time = date.toLocaleTimeString()
this.changesA.push(obj[i])
this.changesB.push(obj[i])
this.$emit('update:changesA', this.localChanges.A)
this.$emit('update:changesB', this.localChanges.B)
}
},
replaceNumbersArray () { // replace random A, B numbers at time interval
const numberA = Number((Math.random() * 1 + 1).toFixed(2)) // first number A
const numberB = Number((Math.random() * 1 + 1).toFixed(2)) // first number B
this.randomNumbersArray.splice(0, 2, numberA, numberB)
},
toggleInterval (field) { // button toggle
if (field === 'A') {
this.startStop.A = !this.startStop.A
if (this.startStop.A) {
this.timerA = setInterval(() => { this.calculations('A') }, 2000)
} else {
clearInterval(this.timerA)
}
}
if (field === 'B') {
this.startStop.B = !this.startStop.B
if (this.startStop.B) {
this.timerB = setInterval(() => { this.calculations('B') }, 2000)
} else {
clearInterval(this.timerB)
}
}
},
calculations (field) {
if (field === 'A') {
this.randomSign.A = this.signsArray[
Math.floor(Math.random() * this.signsArray.length)
]
this.randomSign.A === '+'
? (this.initialValueA += this.randomNumbersArray[0])
: (this.initialValueA -= this.randomNumbersArray[0])
const date = new Date()
const newChange = {}
newChange.field = 'A'
newChange.value = this.randomNumbersArray[0]
newChange.time = date.toLocaleTimeString()
this.changesA.push(newChange)
this.$emit('update:changesA', this.localChanges.A)
}
if (field === 'B') {
this.randomSign.B = this.signsArray[
Math.floor(Math.random() * this.signsArray.length)
]
this.randomSign.B === '+'
? (this.initialValueB += this.randomNumbersArray[1])
: (this.initialValueB -= this.randomNumbersArray[1])
const date = new Date()
const newChange = {}
newChange.field = 'B'
newChange.value = this.randomNumbersArray[1]
newChange.time = date.toLocaleTimeString()
this.changesB.push(newChange)
this.$emit('update:changesB', this.localChanges.B)
}
}
},
mounted () {
this.firstObjects()
setInterval(this.replaceNumbersArray, 2000)
this.initialValueA = this.$root.initialValueA || 3
this.timerA = setInterval(() => {
this.calculations('A')
}, 2000)
this.initialValueB = this.$root.initialValueB || 3
this.timerB = setInterval(() => {
this.calculations('B')
}, 2000)
},
beforeDestroy () {
this.$root.initialValueA = this.initialValueA
this.$root.initialValueB = this.initialValueB
clearInterval(this.timerA)
clearInterval(this.timerB)
}
}
</script>
<style lang="scss" scoped>
button {
margin-bottom: 15px;
&:last-child {
margin-bottom: 0;
}
}
.sign {
width: 12px;
text-align: center;
}
button {
border: 1px solid transparent;
border-radius: 0;
background-color: #42b983;
color: #ffffff;
margin-top: 7px;
padding: 5px 10px;
&:hover {
opacity: 0.9;
cursor: pointer;
}
}
</style>
例如:
function accAdd(arg1, arg2) {
var r1, r2, m;
try {
r1 = arg1.toString().split(".")[1].length;
} catch(e) {
r1 = 0;
}
try {
r2 = arg2.toString().split(".")[1].length;
}catch(e){
r2 = 0;
}
m = Math.pow(10, Math.max(r1, r2));
return(arg1 * m + arg2 * m) / m;
}
计算时,保留数字。显示的时候,把它们变成想要的格式。
这个需要补充:
computed: {
valueA () {
return this.initialValueA.toFixed(2)
},
valueB () {
return this.initialValueB.toFixed(2)
}
}
然后像这样调用模板中的函数:
<td>{{ valueA }}</td>
和 <td>{{ valueB }}</td>
而不是
<td>{{ initialValueA }}</td>
和 <td>{{ initialValueA }}</td>
所有致谢来自 discord 的“kusu”。