diff --git a/packages/components/_util/number.ts b/packages/components/_util/number.ts index 21a832f3c0..bc3585be4f 100644 --- a/packages/components/_util/number.ts +++ b/packages/components/_util/number.ts @@ -1,28 +1,21 @@ -/** - ** 加法函数,用来得到精确的加法结果 - ** 说明:javascript 的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。 - ** 调用:accAdd(num1,num2) - ** 返回值:num1 加上num2 的精确结果 - * */ -export function accAdd(num1: number, num2: number) { - const isFloat = (n: number) => typeof n === 'number' && !Number.isInteger(n); - - if (isFloat(num1) && isFloat(num2)) { - const [integer1, precision1] = String(num1).split('.'); - const [integer2, precision2] = String(num2).split('.'); +export const numberToPercent = (number: number) => `${number * 100}%`; - // 获取两个浮点数的最长精度 - const maxPrecisionLen = Math.max(precision1.length, precision2.length); - // 对齐小数部分的精度长度 - const wholePrecision1 = Number(precision1.padEnd(maxPrecisionLen, '0')); - const wholePrecision2 = Number(precision2.padEnd(maxPrecisionLen, '0')); +/** + * 精确加法函数,避免 JavaScript 浮点误差 + * - 浮点运算会导致类似 0.1 + 0.2 = 0.30000000000000004 的问题 + * - 该函数通过将数字放大为整数进行运算,再缩小回原精度,得到更精确的结果 + */ +export function accAdd(num1: number, num2: number): number { + // 获取每个数字的小数位长度 + const precision1 = (num1.toString().split('.')[1] || '').length; + const precision2 = (num2.toString().split('.')[1] || '').length; - // 小数部分转化成整数相加之后除以精度最长的 10 的倍数 - const precisionVal = (wholePrecision1 + wholePrecision2) / 10 ** maxPrecisionLen; - const integerVal = Number(integer1) + Number(integer2); + // 取两者中较大的小数位长度,用于计算放大倍数 + const scale = 10 ** Math.max(precision1, precision2); - return integerVal + precisionVal; - } + // 将小数放大为整数 + const sum = Math.round(num1 * scale) + Math.round(num2 * scale); - return num1 + num2; + // 缩放回原精度,得到最终结果 + return sum / scale; } diff --git a/packages/components/slider/Slider.tsx b/packages/components/slider/Slider.tsx index 6542997b60..e213e46b05 100644 --- a/packages/components/slider/Slider.tsx +++ b/packages/components/slider/Slider.tsx @@ -1,18 +1,19 @@ import React, { useMemo, useRef } from 'react'; import classNames from 'classnames'; -import { isFunction, isString, isNumber } from 'lodash-es'; +import { isFunction, isNumber, isString } from 'lodash-es'; + import { largeNumberToFixed } from '@tdesign/common-js/input-number/large-number'; -import { accAdd } from '../_util/number'; -import type { StyledProps, TNode } from '../common'; +import { accAdd, numberToPercent } from '../_util/number'; import useConfig from '../hooks/useConfig'; import useControlled from '../hooks/useControlled'; import useDefaultProps from '../hooks/useDefaultProps'; -import type { MouseCallback } from '../hooks/useMouseEvent'; import InputNumber from '../input-number/InputNumber'; import { sliderDefaultProps } from './defaultProps'; import SliderHandleButton from './SliderHandleButton'; + +import type { StyledProps, TNode } from '../common'; +import type { MouseCallback } from '../hooks/useMouseEvent'; import type { TdSliderProps } from './type'; -import { numberToPercent } from './utils/handleNumber'; export type SliderProps = TdSliderProps & StyledProps; diff --git a/packages/components/slider/utils/handleNumber.ts b/packages/components/slider/utils/handleNumber.ts deleted file mode 100644 index 21a9f2ddc1..0000000000 --- a/packages/components/slider/utils/handleNumber.ts +++ /dev/null @@ -1 +0,0 @@ -export const numberToPercent = (number: number) => `${number * 100}%`; diff --git a/packages/tdesign-react/CHANGELOG.md b/packages/tdesign-react/CHANGELOG.md index e3e59f7818..4ae9580d2a 100644 --- a/packages/tdesign-react/CHANGELOG.md +++ b/packages/tdesign-react/CHANGELOG.md @@ -282,7 +282,7 @@ spline: explain - `Guide`: 优化组件在屏幕大小变化时没有重新计算位置的问题 @HaixingOoO ([#3543](https://github.com/Tencent/tdesign-react/pull/3543)) - `List`: 修复空子节点导致获取子节点 `props` 失败的问题 @RSS1102 ([#3570](https://github.com/Tencent/tdesign-react/pull/3570)) - `Popconfirm`: 修复 `confirmBtn` 属性的 children 不生效的问题 @huangchen1031 ([#3556](https://github.com/Tencent/tdesign-react/pull/3556)) -- `Slider`: 修复 `Slider` 的 最后一个 label 宽度不足自动换行的问题 @l123wx([#3581](https://github.com/Tencent/tdesign-react/pull/3581)) +- `Slider`: 修复最后一个 `label` 宽度不足自动换行的问题 @l123wx([#3581](https://github.com/Tencent/tdesign-react/pull/3581)) - `Textarea`: 修复输入中文被中断的问题 @betavs ([#3544](https://github.com/Tencent/tdesign-react/pull/3544)) - `TreeSelect`: 修复单点已选中的值时,会删除已选中的值的问题 @HaixingOoO ([#3573](https://github.com/Tencent/tdesign-react/pull/3573)) @@ -1019,7 +1019,7 @@ spline: explain - 拖拽排序 + 本地数据分页场景,修复拖拽排序事件参数 `currentIndex/targetIndex/current/target` 等不正确问题 - 拖拽排序 + 本地数据分页场景,修复在第二页以后的分页数据中拖拽调整顺序后,会自动跳转到第一页问题 - 支持分页非受控用法的拖拽排序场景 -- `Slider`: 修复初始值为0 时,label位置错误的缺陷 @Zzongke ([#2477](https://github.com/Tencent/tdesign-react/pull/2477)) +- `Slider`: 修复初始值为 0 时,`label` 位置错误的缺陷 @Zzongke ([#2477](https://github.com/Tencent/tdesign-react/pull/2477)) - `Tree`: 支持`store.children`调用getChildren方法 @uyarn ([#2480](https://github.com/Tencent/tdesign-react/pull/2480)) ## 🌈 1.2.3 `2023-08-24`