github.com/elves/elvish@v0.15.0/pkg/eval/mods/math/math.go (about)

     1  // Package math exposes functionality from Go's math package as an elvish
     2  // module.
     3  package math
     4  
     5  import (
     6  	"math"
     7  
     8  	"github.com/elves/elvish/pkg/eval"
     9  	"github.com/elves/elvish/pkg/eval/vars"
    10  )
    11  
    12  //elvdoc:var e
    13  //
    14  // ```elvish
    15  // $math:e
    16  // ```
    17  //
    18  // The value of
    19  // [`e`](https://en.wikipedia.org/wiki/E_(mathematical_constant)):
    20  // 2.718281.... This variable is read-only.
    21  
    22  //elvdoc:var pi
    23  //
    24  // ```elvish
    25  // $math:pi
    26  // ```
    27  //
    28  // The value of [`π`](https://en.wikipedia.org/wiki/Pi): 3.141592.... This
    29  // variable is read-only.
    30  
    31  //elvdoc:fn abs
    32  //
    33  // ```elvish
    34  // math:abs $number
    35  // ```
    36  //
    37  // Computes the absolute value `$number`. Examples:
    38  //
    39  // ```elvish-transcript
    40  // ~> math:abs 1.2
    41  // ▶ (float64 1.2)
    42  // ~> math:abs -5.3
    43  // ▶ (float64 5.3)
    44  // ```
    45  
    46  //elvdoc:fn ceil
    47  //
    48  // ```elvish
    49  // math:ceil $number
    50  // ```
    51  //
    52  // Computes the ceiling of `$number`.
    53  // Read the [Go documentation](https://godoc.org/math#Ceil) for the details of
    54  // how this behaves. Examples:
    55  //
    56  // ```elvish-transcript
    57  // ~> math:ceil 1.1
    58  // ▶ (float64 2)
    59  // ~> math:ceil -2.3
    60  // ▶ (float64 -2)
    61  // ```
    62  
    63  //elvdoc:fn acos
    64  //
    65  // ```elvish
    66  // math:acos $number
    67  // ```
    68  //
    69  // Outputs the arccosine of `$number`, in radians (not degrees). Examples:
    70  //
    71  // ```elvish-transcript
    72  // ~> math:acos 1
    73  // ▶ (float64 1)
    74  // ~> math:acos 1.00001
    75  // ▶ (float64 NaN)
    76  // ```
    77  
    78  //elvdoc:fn acosh
    79  //
    80  // ```elvish
    81  // math:acosh $number
    82  // ```
    83  //
    84  // Outputs the inverse hyperbolic cosine of `$number`. Examples:
    85  //
    86  // ```elvish-transcript
    87  // ~> math:acosh 1
    88  // ▶ (float64 0)
    89  // ~> math:acosh 0
    90  // ▶ (float64 NaN)
    91  // ```
    92  
    93  //elvdoc:fn asin
    94  //
    95  // ```elvish
    96  // math:asin $number
    97  // ```
    98  //
    99  // Outputs the arcsine of `$number`, in radians (not degrees). Examples:
   100  //
   101  // ```elvish-transcript
   102  // ~> math:asin 0
   103  // ▶ (float64 0)
   104  // ~> math:asin 1
   105  // ▶ (float64 1.5707963267948966)
   106  // ~> math:asin 1.00001
   107  // ▶ (float64 NaN)
   108  // ```
   109  
   110  //elvdoc:fn asinh
   111  //
   112  // ```elvish
   113  // math:asinh $number
   114  // ```
   115  //
   116  // Outputs the inverse hyperbolic sine of `$number`. Examples:
   117  //
   118  // ```elvish-transcript
   119  // ~> math:asinh 0
   120  // ▶ (float64 0)
   121  // ~> math:asinh inf
   122  // ▶ (float64 +Inf)
   123  // ```
   124  
   125  //elvdoc:fn atan
   126  //
   127  // ```elvish
   128  // math:atan $number
   129  // ```
   130  //
   131  // Outputs the arctangent of `$number`, in radians (not degrees). Examples:
   132  //
   133  // ```elvish-transcript
   134  // ~> math:atan 0
   135  // ▶ (float64 0)
   136  // ~> math:atan $math:inf
   137  // ▶ (float64 1.5707963267948966)
   138  // ```
   139  
   140  //elvdoc:fn atanh
   141  //
   142  // ```elvish
   143  // math:atanh $number
   144  // ```
   145  //
   146  // Outputs the inverse hyperbolic tangent of `$number`. Examples:
   147  //
   148  // ```elvish-transcript
   149  // ~> math:atanh 0
   150  // ▶ (float64 0)
   151  // ~> math:atanh 1
   152  // ▶ (float64 +Inf)
   153  // ```
   154  
   155  //elvdoc:fn cos
   156  //
   157  // ```elvish
   158  // math:cos $number
   159  // ```
   160  //
   161  // Computes the cosine of `$number` in units of radians (not degrees).
   162  // Examples:
   163  //
   164  // ```elvish-transcript
   165  // ~> math:cos 0
   166  // ▶ (float64 1)
   167  // ~> math:cos 3.14159265
   168  // ▶ (float64 -1)
   169  // ```
   170  
   171  //elvdoc:fn cosh
   172  //
   173  // ```elvish
   174  // math:cosh $number
   175  // ```
   176  //
   177  // Computes the hyperbolic cosine of `$number`. Example:
   178  //
   179  // ```elvish-transcript
   180  // ~> math:cosh 0
   181  // ▶ (float64 1)
   182  // ```
   183  
   184  //elvdoc:fn floor
   185  //
   186  // ```elvish
   187  // math:floor $number
   188  // ```
   189  //
   190  // Computes the floor of `$number`.
   191  // Read the [Go documentation](https://godoc.org/math#Floor) for the details of
   192  // how this behaves. Examples:
   193  //
   194  // ```elvish-transcript
   195  // ~> math:floor 1.1
   196  // ▶ (float64 1)
   197  // ~> math:floor -2.3
   198  // ▶ (float64 -3)
   199  // ```
   200  
   201  //elvdoc:fn is-inf
   202  //
   203  // ```elvish
   204  // math:is-inf &sign=0 $number
   205  // ```
   206  //
   207  // Tests whether the number is infinity. If sign > 0, tests whether `$number`
   208  // is positive infinity. If sign < 0, tests whether `$number` is negative
   209  // infinity. If sign == 0, tests whether `$number` is either infinity.
   210  //
   211  // ```elvish-transcript
   212  // ~> math:is-inf 123
   213  // ▶ $false
   214  // ~> math:is-inf inf
   215  // ▶ $true
   216  // ~> math:is-inf -inf
   217  // ▶ $true
   218  // ~> math:is-inf &sign=1 inf
   219  // ▶ $true
   220  // ~> math:is-inf &sign=-1 inf
   221  // ▶ $false
   222  // ~> math:is-inf &sign=-1 -inf
   223  // ▶ $true
   224  // ```
   225  
   226  //elvdoc:fn is-nan
   227  //
   228  // ```elvish
   229  // math:is-nan $number
   230  // ```
   231  //
   232  // Tests whether the number is a NaN (not-a-number).
   233  //
   234  // ```elvish-transcript
   235  // ~> math:is-nan 123
   236  // ▶ $false
   237  // ~> math:is-nan (float64 inf)
   238  // ▶ $false
   239  // ~> math:is-nan (float64 nan)
   240  // ▶ $true
   241  // ```
   242  
   243  //elvdoc:fn log
   244  //
   245  // ```elvish
   246  // math:log $number
   247  // ```
   248  //
   249  // Computes the natural (base *e*) logarithm of `$number`. Examples:
   250  //
   251  // ```elvish-transcript
   252  // ~> math:log 1.0
   253  // ▶ (float64 1)
   254  // ~> math:log -2.3
   255  // ▶ (float64 NaN)
   256  // ```
   257  
   258  //elvdoc:fn log10
   259  //
   260  // ```elvish
   261  // math:log10 $number
   262  // ```
   263  //
   264  // Computes the base 10 logarithm of `$number`. Examples:
   265  //
   266  // ```elvish-transcript
   267  // ~> math:log10 100.0
   268  // ▶ (float64 2)
   269  // ~> math:log10 -1.7
   270  // ▶ (float64 NaN)
   271  // ```
   272  
   273  //elvdoc:fn log2
   274  //
   275  // ```elvish
   276  // math:log2 $number
   277  // ```
   278  //
   279  // Computes the base 2 logarithm of `$number`. Examples:
   280  //
   281  // ```elvish-transcript
   282  // ~> math:log2 8
   283  // ▶ (float64 3)
   284  // ~> math:log2 -5.3
   285  // ▶ (float64 NaN)
   286  // ```
   287  
   288  //elvdoc:fn max
   289  //
   290  // ```elvish
   291  // math:max $number...
   292  // ```
   293  //
   294  // Outputs the maximum number in the arguments. If there are no arguments
   295  // an exception is thrown. If any number is NaN then NaN is output.
   296  //
   297  // Examples:
   298  //
   299  // ```elvish-transcript
   300  // ~> put ?(math:max)
   301  // ▶ ?(fail 'arity mismatch: arguments here must be 1 or more values, but is 0 values')
   302  // ~> math:max 3
   303  // ▶ (float 3)
   304  // ~> math:max 3 5 2
   305  // ▶ (float 5)
   306  // ~> range 100 | math:max (all)
   307  // ▶ (float 99)
   308  // ```
   309  
   310  //elvdoc:fn min
   311  //
   312  // ```elvish
   313  // math:min $number...
   314  // ```
   315  //
   316  // Outputs the minimum number in the arguments. If there are no arguments
   317  // an exception is thrown. If any number is NaN then NaN is output.
   318  //
   319  // Examples:
   320  //
   321  // ```elvish-transcript
   322  // ~> put ?(math:min)
   323  // ▶ ?(fail 'arity mismatch: arguments here must be 1 or more values, but is 0 values')
   324  // ~> math:min 3
   325  // ▶ (float 3)
   326  // ~> math:min 3 5 2
   327  // ▶ (float 2)
   328  // ~> range 100 | math:min (all)
   329  // ▶ (float 0)
   330  // ```
   331  
   332  //elvdoc:fn pow
   333  //
   334  // ```elvish
   335  // math:pow $base $exponent
   336  // ```
   337  //
   338  // Output the result of raising `$base` to the power of `$exponent`. Examples:
   339  //
   340  // ```elvish-transcript
   341  // ~> math:pow 3 2
   342  // ▶ (float64 9)
   343  // ~> math:pow -2 2
   344  // ▶ (float64 4)
   345  // ```
   346  //
   347  // @cf math:pow10
   348  
   349  //elvdoc:fn pow10
   350  //
   351  // ```elvish
   352  // math:pow10 $exponent
   353  // ```
   354  //
   355  // Output the result of raising ten to the power of `$exponent` which must be
   356  // an integer. Note that `$exponent > 308` results in +Inf and `$exponent <
   357  // -323` results in zero. Examples:
   358  //
   359  // ```elvish-transcript
   360  // ~> math:pow10 2
   361  // ▶ (float64 100)
   362  // ~> math:pow10 -3
   363  // ▶ (float64 0.001)
   364  // ```
   365  //
   366  // @cf math:pow
   367  
   368  //elvdoc:fn round
   369  //
   370  // ```elvish
   371  // math:round $number
   372  // ```
   373  //
   374  // Outputs the nearest integer, rounding half away from zero.
   375  //
   376  // ```elvish-transcript
   377  // ~> math:round -1.1
   378  // ▶ (float64 -1)
   379  // ~> math:round 2.5
   380  // ▶ (float64 3)
   381  // ```
   382  
   383  //elvdoc:fn round-to-even
   384  //
   385  // ```elvish
   386  // math:round-to-even $number
   387  // ```
   388  //
   389  // Outputs the nearest integer, rounding ties to even. Examples:
   390  //
   391  // ```elvish-transcript
   392  // ~> math:round-to-even -1.1
   393  // ▶ (float64 -1)
   394  // ~> math:round-to-even 2.5
   395  // ▶ (float64 2)
   396  // ```
   397  
   398  //elvdoc:fn sin
   399  //
   400  // ```elvish
   401  // math:sin $number
   402  // ```
   403  //
   404  // Computes the sine of `$number` in units of radians (not degrees). Examples:
   405  //
   406  // ```elvish-transcript
   407  // ~> math:sin 0
   408  // ▶ (float64 0)
   409  // ~> math:sin 3.14159265
   410  // ▶ (float64 3.5897930298416118e-09)
   411  // ```
   412  
   413  //elvdoc:fn sinh
   414  //
   415  // ```elvish
   416  // math:sinh $number
   417  // ```
   418  //
   419  // Computes the hyperbolic sine of `$number`. Example:
   420  //
   421  // ```elvish-transcript
   422  // ~> math:sinh 0
   423  // ▶ (float64 0)
   424  // ```
   425  
   426  //elvdoc:fn sqrt
   427  //
   428  // ```elvish
   429  // math:sqrt $number
   430  // ```
   431  //
   432  // Computes the square-root of `$number`. Examples:
   433  //
   434  // ```elvish-transcript
   435  // ~> math:sqrt 0
   436  // ▶ (float64 0)
   437  // ~> math:sqrt 4
   438  // ▶ (float64 2)
   439  // ~> math:sqrt -4
   440  // ▶ (float64 NaN)
   441  // ```
   442  
   443  //elvdoc:fn tan
   444  //
   445  // ```elvish
   446  // math:tan $number
   447  // ```
   448  //
   449  // Computes the tangent of `$number` in units of radians (not degrees). Examples:
   450  //
   451  // ```elvish-transcript
   452  // ~> math:tan 0
   453  // ▶ (float64 0)
   454  // ~> math:tan 3.14159265
   455  // ▶ (float64 -0.0000000035897930298416118)
   456  // ```
   457  
   458  //elvdoc:fn tanh
   459  //
   460  // ```elvish
   461  // math:tanh $number
   462  // ```
   463  //
   464  // Computes the hyperbolic tangent of `$number`. Example:
   465  //
   466  // ```elvish-transcript
   467  // ~> math:tanh 0
   468  // ▶ (float64 0)
   469  // ```
   470  
   471  //elvdoc:fn trunc
   472  //
   473  // ```elvish
   474  // math:trunc $number
   475  // ```
   476  //
   477  // Outputs the integer portion of `$number`.
   478  //
   479  // ```elvish-transcript
   480  // ~> math:trunc -1.1
   481  // ▶ (float64 -1)
   482  // ~> math:trunc 2.5
   483  // ▶ (float64 2)
   484  // ```
   485  
   486  // Ns is the namespace for the math: module.
   487  var Ns = eval.NsBuilder{
   488  	"e":  vars.NewReadOnly(math.E),
   489  	"pi": vars.NewReadOnly(math.Pi),
   490  }.AddGoFns("math:", fns).Ns()
   491  
   492  var fns = map[string]interface{}{
   493  	"abs":           math.Abs,
   494  	"acos":          math.Acos,
   495  	"acosh":         math.Acosh,
   496  	"asin":          math.Asin,
   497  	"asinh":         math.Asinh,
   498  	"atan":          math.Atan,
   499  	"atanh":         math.Atanh,
   500  	"ceil":          math.Ceil,
   501  	"cos":           math.Cos,
   502  	"cosh":          math.Cosh,
   503  	"floor":         math.Floor,
   504  	"is-inf":        isInf,
   505  	"is-nan":        math.IsNaN,
   506  	"log":           math.Log,
   507  	"log10":         math.Log10,
   508  	"log2":          math.Log2,
   509  	"max":           max,
   510  	"min":           min,
   511  	"pow":           math.Pow,
   512  	"pow10":         math.Pow10,
   513  	"round":         math.Round,
   514  	"round-to-even": math.RoundToEven,
   515  	"sin":           math.Sin,
   516  	"sinh":          math.Sinh,
   517  	"sqrt":          math.Sqrt,
   518  	"tan":           math.Tan,
   519  	"tanh":          math.Tanh,
   520  	"trunc":         math.Trunc,
   521  }
   522  
   523  type isInfOpts struct{ Sign int }
   524  
   525  func (opts *isInfOpts) SetDefaultOptions() { opts.Sign = 0 }
   526  
   527  func isInf(opts isInfOpts, arg float64) bool {
   528  	return math.IsInf(arg, opts.Sign)
   529  }
   530  
   531  func max(num float64, nums ...float64) float64 {
   532  	for i := 0; i < len(nums); i++ {
   533  		num = math.Max(num, nums[i])
   534  	}
   535  	return num
   536  }
   537  
   538  func min(num float64, nums ...float64) float64 {
   539  	for i := 0; i < len(nums); i++ {
   540  		num = math.Min(num, nums[i])
   541  	}
   542  	return num
   543  }