【问题标题】:How can I add "deg" after all numbers in trig functions?如何在三角函数中的所有数字后添加“度”?
【发布时间】:2026-01-31 21:45:01
【问题描述】:

我将 Node.js 与 mathjs 包一起使用。 Mathjs 在其三角函数中使用弧度。我想为我正在制作的计算器添加学位模式。如何在字符串中的任何 sin/cos/tan 函数中的每个数字后添加“deg”?这样,mathjs 将使用度数来计算它,因此它可以工作。

例如:5*(2+3)/sin(4+(3-2)) 应该变成 5*(2+3)/sin(4deg+(3deg-2deg)) 但是:5*(2+3)/(4+(3-2)) 不应更改。

我到处找:正则表达式、reddit、google,我什么也没找到。我最接近的是一个正则表达式,当 sin 函数中有括号时会中断 (/sin\(.*?\)/)。

编辑:是的,我看过角度配置示例。不,这不能解决我的问题:它假设用户正在实现单个值来计算正弦值,我正在尝试使用度数模式计算完整表达式 (mathjs.evaluate())

【问题讨论】:

  • 正则表达式很难匹配平衡括号。您应该使用递归下降解析器。
  • 是的,我已经读过了。不,我不能替换这些功能,我需要它是可切换的。
  • 我想您不希望在sin(atan(5)) 中添加“deg”?
  • 但是该示例已经可以切换...它正在用尊重切换的版本替换功能...玩deg无论如何都不会工作,因为您可能也有弧形功能,例如sin(15 + acos(0.5)) 应该被解释为sin(15deg + acos(0.5)) 而不是sin(15deg + acos(0.5deg)),而是你希望acos 在此处返回 度。替换函数应该可以让您正确地完成所有操作。
  • “它假设用户正在实现单个值来计算正弦值,我正在尝试使用度数模式计算完整表达式 (mathjs.evaluate())” - 这不是真的。跨度>

标签: javascript node.js mathjs


【解决方案1】:

您可以简单地将三角函数实现替换为使用度数的版本...

查看angle configuration example in the MathJS docs。您可以使用math.import函数为sincos等提供自己的函数实现,您可以通过先保存对它们的引用来参考原始的。

这是来自链接文档的完整示例,可运行 sn-p(版权所有 © 2013-2021 jos de jong):

  let replacements = {}

  // our extended configuration options
  const config = {
    angles: 'deg' // 'rad', 'deg', 'grad'
  }

  // create trigonometric functions replacing the input depending on angle config
  const fns1 = ['sin', 'cos', 'tan', 'sec', 'cot', 'csc']
  fns1.forEach(function(name) {
    const fn = math[name] // the original function

    const fnNumber = function (x) {
      // convert from configured type of angles to radians
      switch (config.angles) {
        case 'deg':
          return fn(x / 360 * 2 * Math.PI)
        case 'grad':
          return fn(x / 400 * 2 * Math.PI)
        default:
          return fn(x)
      }
    }

    // create a typed-function which check the input types
    replacements[name] = math.typed(name, {
      'number': fnNumber,
      'Array | Matrix': function (x) {
        return math.map(x, fnNumber)
      }
    })
  })

  // create trigonometric functions replacing the output depending on angle config
  const fns2 = ['asin', 'acos', 'atan', 'atan2', 'acot', 'acsc', 'asec']
  fns2.forEach(function(name) {
    const fn = math[name] // the original function

    const fnNumber = function (x) {
      const result = fn(x)

      if (typeof result === 'number') {
        // convert to radians to configured type of angles
        switch(config.angles) {
          case 'deg':  return result / 2 / Math.PI * 360
          case 'grad': return result / 2 / Math.PI * 400
          default: return result
        }
      }

      return result
    }

    // create a typed-function which check the input types
    replacements[name] = math.typed(name, {
      'number': fnNumber,
      'Array | Matrix': function (x) {
        return math.map(x, fnNumber)
      }
    })
  })

  // import all replacements into math.js, override existing trigonometric functions
  math.import(replacements, {override: true})

  // pointers to the input elements
  const expression = document.getElementById('expression')
  const evaluate   = document.getElementById('evaluate')
  const result     = document.getElementById('result')
  const angles     = document.getElementById('angles')

  // attach event handlers for select box and button
  angles.onchange = function () {
    config.angles = this.value
    config.angles = this.value
  }
  evaluate.onclick = function () {
    result.innerHTML = math.evaluate(expression.value)
  }
<script src="https://unpkg.com/mathjs@10.0.2/lib/browser/math.js"></script>

<table>
  <tr>
    <th>Angles</th>
    <td>
      <select id="angles">
        <option value="deg">deg</option>
        <option value="grad">grad</option>
        <option value="rad">rad</option>
      </select>
    </td>
  </tr>
  <tr>
    <th>Expression</th>
    <td>
      <input id="expression" type="text" value="sin(45)" />
      <input id="evaluate" type="button" value="Evaluate">
    </td>
  </tr>
  <tr>
    <th>Result</th>
    <td id="result"></td>
  </tr>
</table>

编辑:回复问题中的编辑:

编辑:是的,我看过角度配置示例。不,这不能解决我的问题:它假设用户正在实现单个值来计算正弦值,我正在尝试使用度数模式计算完整表达式 (mathjs.evaluate())

那不是真的。它不假设。正如您所说,该示例使用math.evaluate。它应该完全按照您的需要工作。它的工作方式只是新的替换函数在决定解释输入的内容时引用 config.angles 值(或者在 arcus 函数的情况下,在返回之前将其结果转换为什么)。

【讨论】:

  • 是否可以为学位版本创建新功能?例如: sindeg() 将是 sin() 但对于度数。
  • 当然,给它们起不同的名字(然后你就不需要override开关了),你不需要保存旧的函数实例,你可以直接从math 对象,因为您永远不会覆盖它们。当然,然后您会将学位模式硬编码到它们中,而不是引用示例使用的配置对象。