Как решить вычисление плавающих чисел - PullRequest
0 голосов
/ 18 апреля 2020

В моем приложении есть вычисления между двумя плавающими числами. Хотя применяется метод 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 == '+'">&#x2B06;</td>
        <td v-show="this.randomSign.A == '-'">&#x2B07;</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 == '+'">&#x2B06;</td>
        <td v-show="this.randomSign.B == '-'">&#x2B07;</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>

Ответы [ 2 ]

1 голос
/ 18 апреля 2020

Например:

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;

}
0 голосов
/ 18 апреля 2020

При расчете сохраняйте числа как числа. При отображении поверните их в нужный формат.
Это необходимо добавить:

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>

Все кредиты go в "ク ス" от раздора.

...