kcl_lib/std/math.rs
1//! Functions related to mathematics.
2
3use anyhow::Result;
4use kcl_derive_docs::stdlib;
5
6use super::args::FromArgs;
7use crate::{
8 errors::{KclError, KclErrorDetails},
9 execution::{ExecState, KclValue},
10 std::args::{Args, TyF64},
11};
12
13/// Compute the remainder after dividing `num` by `div`.
14/// If `num` is negative, the result will be too.
15pub async fn rem(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
16 let n = args.get_unlabeled_kw_arg("number to divide")?;
17 let d = args.get_kw_arg("divisor")?;
18 let remainder = inner_rem(n, d);
19
20 Ok(args.make_user_val_from_f64(remainder))
21}
22
23/// Compute the remainder after dividing `num` by `div`.
24/// If `num` is negative, the result will be too.
25///
26/// ```no_run
27/// assertEqual(rem( 7, divisor = 4), 3, 0.01, "remainder is 3" )
28/// assertEqual(rem(-7, divisor = 4), -3, 0.01, "remainder is -3")
29/// assertEqual(rem( 7, divisor = -4), 3, 0.01, "remainder is 3" )
30/// assertEqual(rem( 6, divisor = 2.5), 1, 0.01, "remainder is 1" )
31/// assertEqual(rem( 6.5, divisor = 2.5), 1.5, 0.01, "remainder is 1.5" )
32/// assertEqual(rem( 6.5, divisor = 2), 0.5, 0.01, "remainder is 0.5" )
33/// ```
34#[stdlib {
35 name = "rem",
36 tags = ["math"],
37 keywords = true,
38 unlabeled_first = true,
39 args = {
40 num = {docs = "The number which will be divided by `divisor`."},
41 divisor = {docs = "The number which will divide `num`."},
42 }
43}]
44fn inner_rem(num: f64, divisor: f64) -> f64 {
45 num % divisor
46}
47
48/// Compute the cosine of a number (in radians).
49pub async fn cos(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
50 let num = args.get_number()?;
51 Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.cos())))
52}
53
54/// Compute the sine of a number (in radians).
55pub async fn sin(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
56 let num = args.get_number()?;
57 Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.sin())))
58}
59
60/// Compute the tangent of a number (in radians).
61pub async fn tan(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
62 let num = args.get_number()?;
63 Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.tan())))
64}
65
66/// Return the value of `pi`. Archimedes’ constant (π).
67pub async fn pi(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
68 let result = inner_pi()?;
69
70 Ok(args.make_user_val_from_f64(result))
71}
72
73/// Return the value of `pi`. Archimedes’ constant (π).
74///
75/// **DEPRECATED** use the constant PI
76///
77/// ```no_run
78/// circumference = 70
79///
80/// exampleSketch = startSketchOn("XZ")
81/// |> circle( center = [0, 0], radius = circumference/ (2 * pi()) )
82///
83/// example = extrude(exampleSketch, length = 5)
84/// ```
85#[stdlib {
86 name = "pi",
87 tags = ["math"],
88 deprecated = true,
89}]
90fn inner_pi() -> Result<f64, KclError> {
91 Ok(std::f64::consts::PI)
92}
93
94/// Compute the square root of a number.
95pub async fn sqrt(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
96 let num = args.get_number()?;
97 let result = inner_sqrt(num)?;
98
99 Ok(args.make_user_val_from_f64(result))
100}
101
102/// Compute the square root of a number.
103///
104/// ```no_run
105/// exampleSketch = startSketchOn("XZ")
106/// |> startProfileAt([0, 0], %)
107/// |> angledLine({
108/// angle = 50,
109/// length = sqrt(2500),
110/// }, %)
111/// |> yLine(endAbsolute = 0)
112/// |> close()
113///
114/// example = extrude(exampleSketch, length = 5)
115/// ```
116#[stdlib {
117 name = "sqrt",
118 tags = ["math"],
119}]
120fn inner_sqrt(num: f64) -> Result<f64, KclError> {
121 Ok(num.sqrt())
122}
123
124/// Compute the absolute value of a number.
125pub async fn abs(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
126 let num = args.get_number()?;
127 let result = inner_abs(num)?;
128
129 Ok(args.make_user_val_from_f64(result))
130}
131
132/// Compute the absolute value of a number.
133///
134/// ```no_run
135/// myAngle = -120
136///
137/// sketch001 = startSketchOn('XZ')
138/// |> startProfileAt([0, 0], %)
139/// |> line(end = [8, 0])
140/// |> angledLine({
141/// angle = abs(myAngle),
142/// length = 5,
143/// }, %)
144/// |> line(end = [-5, 0])
145/// |> angledLine({
146/// angle = myAngle,
147/// length = 5,
148/// }, %)
149/// |> close()
150///
151/// baseExtrusion = extrude(sketch001, length = 5)
152/// ```
153#[stdlib {
154 name = "abs",
155 tags = ["math"],
156}]
157fn inner_abs(num: f64) -> Result<f64, KclError> {
158 Ok(num.abs())
159}
160
161/// Round a number to the nearest integer.
162pub async fn round(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
163 let num = args.get_number()?;
164 let result = inner_round(num)?;
165
166 Ok(args.make_user_val_from_f64(result))
167}
168
169/// Round a number to the nearest integer.
170///
171/// ```no_run
172/// sketch001 = startSketchOn('XZ')
173/// |> startProfileAt([0, 0], %)
174/// |> line(endAbsolute = [12, 10])
175/// |> line(end = [round(7.02986), 0])
176/// |> yLine(endAbsolute = 0)
177/// |> close()
178///
179/// extrude001 = extrude(sketch001, length = 5)
180/// ```
181#[stdlib {
182 name = "round",
183 tags = ["math"],
184}]
185fn inner_round(num: f64) -> Result<f64, KclError> {
186 Ok(num.round())
187}
188
189/// Compute the largest integer less than or equal to a number.
190pub async fn floor(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
191 let num = args.get_number()?;
192 let result = inner_floor(num)?;
193
194 Ok(args.make_user_val_from_f64(result))
195}
196
197/// Compute the largest integer less than or equal to a number.
198///
199/// ```no_run
200/// sketch001 = startSketchOn('XZ')
201/// |> startProfileAt([0, 0], %)
202/// |> line(endAbsolute = [12, 10])
203/// |> line(end = [floor(7.02986), 0])
204/// |> yLine(endAbsolute = 0)
205/// |> close()
206///
207/// extrude001 = extrude(sketch001, length = 5)
208/// ```
209#[stdlib {
210 name = "floor",
211 tags = ["math"],
212}]
213fn inner_floor(num: f64) -> Result<f64, KclError> {
214 Ok(num.floor())
215}
216
217/// Compute the smallest integer greater than or equal to a number.
218pub async fn ceil(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
219 let num = args.get_number()?;
220 let result = inner_ceil(num)?;
221
222 Ok(args.make_user_val_from_f64(result))
223}
224
225/// Compute the smallest integer greater than or equal to a number.
226///
227/// ```no_run
228/// sketch001 = startSketchOn('XZ')
229/// |> startProfileAt([0, 0], %)
230/// |> line(endAbsolute = [12, 10])
231/// |> line(end = [ceil(7.02986), 0])
232/// |> yLine(endAbsolute = 0)
233/// |> close()
234///
235/// extrude001 = extrude(sketch001, length = 5)
236/// ```
237#[stdlib {
238 name = "ceil",
239 tags = ["math"],
240}]
241fn inner_ceil(num: f64) -> Result<f64, KclError> {
242 Ok(num.ceil())
243}
244
245/// Compute the minimum of the given arguments.
246pub async fn min(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
247 let nums = args.get_number_array()?;
248 let result = inner_min(nums);
249
250 Ok(args.make_user_val_from_f64(result))
251}
252
253/// Compute the minimum of the given arguments.
254///
255/// ```no_run
256/// exampleSketch = startSketchOn("XZ")
257/// |> startProfileAt([0, 0], %)
258/// |> angledLine({
259/// angle = 70,
260/// length = min(15, 31, 4, 13, 22)
261/// }, %)
262/// |> line(end = [20, 0])
263/// |> close()
264///
265/// example = extrude(exampleSketch, length = 5)
266/// ```
267#[stdlib {
268 name = "min",
269 tags = ["math"],
270}]
271fn inner_min(args: Vec<f64>) -> f64 {
272 let mut min = f64::MAX;
273 for arg in args.iter() {
274 if *arg < min {
275 min = *arg;
276 }
277 }
278
279 min
280}
281
282/// Compute the maximum of the given arguments.
283pub async fn max(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
284 let nums = args.get_number_array()?;
285 let result = inner_max(nums);
286
287 Ok(args.make_user_val_from_f64(result))
288}
289
290/// Compute the maximum of the given arguments.
291///
292/// ```no_run
293/// exampleSketch = startSketchOn("XZ")
294/// |> startProfileAt([0, 0], %)
295/// |> angledLine({
296/// angle = 70,
297/// length = max(15, 31, 4, 13, 22)
298/// }, %)
299/// |> line(end = [20, 0])
300/// |> close()
301///
302/// example = extrude(exampleSketch, length = 5)
303/// ```
304#[stdlib {
305 name = "max",
306 tags = ["math"],
307}]
308fn inner_max(args: Vec<f64>) -> f64 {
309 let mut max = f64::MIN;
310 for arg in args.iter() {
311 if *arg > max {
312 max = *arg;
313 }
314 }
315
316 max
317}
318
319/// Compute the number to a power.
320pub async fn pow(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
321 let nums = args.get_number_array()?;
322 if nums.len() > 2 {
323 return Err(KclError::Type(KclErrorDetails {
324 message: format!("expected 2 arguments, got {}", nums.len()),
325 source_ranges: vec![args.source_range],
326 }));
327 }
328
329 if nums.len() <= 1 {
330 return Err(KclError::Type(KclErrorDetails {
331 message: format!("expected 2 arguments, got {}", nums.len()),
332 source_ranges: vec![args.source_range],
333 }));
334 }
335
336 let result = inner_pow(nums[0], nums[1])?;
337
338 Ok(args.make_user_val_from_f64(result))
339}
340
341/// Compute the number to a power.
342///
343/// ```no_run
344/// exampleSketch = startSketchOn("XZ")
345/// |> startProfileAt([0, 0], %)
346/// |> angledLine({
347/// angle = 50,
348/// length = pow(5, 2),
349/// }, %)
350/// |> yLine(endAbsolute = 0)
351/// |> close()
352///
353/// example = extrude(exampleSketch, length = 5)
354/// ```
355#[stdlib {
356 name = "pow",
357 tags = ["math"],
358}]
359fn inner_pow(num: f64, pow: f64) -> Result<f64, KclError> {
360 Ok(num.powf(pow))
361}
362
363/// Compute the arccosine of a number (in radians).
364pub async fn acos(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
365 let num = args.get_number()?;
366 let result = inner_acos(num)?;
367
368 Ok(args.make_user_val_from_f64(result))
369}
370
371/// Compute the arccosine of a number (in radians).
372///
373/// ```no_run
374/// sketch001 = startSketchOn('XZ')
375/// |> startProfileAt([0, 0], %)
376/// |> angledLine({
377/// angle = toDegrees(acos(0.5)),
378/// length = 10,
379/// }, %)
380/// |> line(end = [5, 0])
381/// |> line(endAbsolute = [12, 0])
382/// |> close()
383///
384/// extrude001 = extrude(sketch001, length = 5)
385/// ```
386#[stdlib {
387 name = "acos",
388 tags = ["math"],
389}]
390fn inner_acos(num: f64) -> Result<f64, KclError> {
391 Ok(num.acos())
392}
393
394/// Compute the arcsine of a number (in radians).
395pub async fn asin(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
396 let num = args.get_number()?;
397 let result = inner_asin(num)?;
398
399 Ok(args.make_user_val_from_f64(result))
400}
401
402/// Compute the arcsine of a number (in radians).
403///
404/// ```no_run
405/// sketch001 = startSketchOn('XZ')
406/// |> startProfileAt([0, 0], %)
407/// |> angledLine({
408/// angle = toDegrees(asin(0.5)),
409/// length = 20,
410/// }, %)
411/// |> yLine(endAbsolute = 0)
412/// |> close()
413///
414/// extrude001 = extrude(sketch001, length = 5)
415/// ```
416#[stdlib {
417 name = "asin",
418 tags = ["math"],
419}]
420fn inner_asin(num: f64) -> Result<f64, KclError> {
421 Ok(num.asin())
422}
423
424/// Compute the arctangent of a number (in radians).
425pub async fn atan(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
426 let num = args.get_number()?;
427 let result = inner_atan(num)?;
428
429 Ok(args.make_user_val_from_f64(result))
430}
431
432/// Compute the arctangent of a number (in radians).
433///
434/// ```no_run
435/// sketch001 = startSketchOn('XZ')
436/// |> startProfileAt([0, 0], %)
437/// |> angledLine({
438/// angle = toDegrees(atan(1.25)),
439/// length = 20,
440/// }, %)
441/// |> yLine(endAbsolute = 0)
442/// |> close()
443///
444/// extrude001 = extrude(sketch001, length = 5)
445/// ```
446#[stdlib {
447 name = "atan",
448 tags = ["math"],
449}]
450fn inner_atan(num: f64) -> Result<f64, KclError> {
451 Ok(num.atan())
452}
453
454/// Compute the four quadrant arctangent of Y and X (in radians).
455pub async fn atan2(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
456 let (y, x) = FromArgs::from_args(&args, 0)?;
457 let result = inner_atan2(y, x)?;
458
459 Ok(args.make_user_val_from_f64(result))
460}
461
462/// Compute the four quadrant arctangent of Y and X (in radians).
463///
464/// ```no_run
465/// sketch001 = startSketchOn('XZ')
466/// |> startProfileAt([0, 0], %)
467/// |> angledLine({
468/// angle = toDegrees(atan2(1.25, 2)),
469/// length = 20,
470/// }, %)
471/// |> yLine(endAbsolute = 0)
472/// |> close()
473///
474/// extrude001 = extrude(sketch001, length = 5)
475/// ```
476#[stdlib {
477 name = "atan2",
478 tags = ["math"],
479}]
480fn inner_atan2(y: f64, x: f64) -> Result<f64, KclError> {
481 Ok(y.atan2(x))
482}
483
484/// Compute the logarithm of the number with respect to an arbitrary base.
485///
486/// The result might not be correctly rounded owing to implementation
487/// details; `log2()` can produce more accurate results for base 2,
488/// and `log10()` can produce more accurate results for base 10.
489pub async fn log(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
490 let nums = args.get_number_array()?;
491 if nums.len() > 2 {
492 return Err(KclError::Type(KclErrorDetails {
493 message: format!("expected 2 arguments, got {}", nums.len()),
494 source_ranges: vec![args.source_range],
495 }));
496 }
497
498 if nums.len() <= 1 {
499 return Err(KclError::Type(KclErrorDetails {
500 message: format!("expected 2 arguments, got {}", nums.len()),
501 source_ranges: vec![args.source_range],
502 }));
503 }
504 let result = inner_log(nums[0], nums[1])?;
505
506 Ok(args.make_user_val_from_f64(result))
507}
508
509/// Compute the logarithm of the number with respect to an arbitrary base.
510///
511/// The result might not be correctly rounded owing to implementation
512/// details; `log2()` can produce more accurate results for base 2,
513/// and `log10()` can produce more accurate results for base 10.
514///
515/// ```no_run
516/// exampleSketch = startSketchOn("XZ")
517/// |> startProfileAt([0, 0], %)
518/// |> line(end = [log(100, 5), 0])
519/// |> line(end = [5, 8])
520/// |> line(end = [-10, 0])
521/// |> close()
522///
523/// example = extrude(exampleSketch, length = 5)
524/// ```
525#[stdlib {
526 name = "log",
527 tags = ["math"],
528}]
529fn inner_log(num: f64, base: f64) -> Result<f64, KclError> {
530 Ok(num.log(base))
531}
532
533/// Compute the base 2 logarithm of the number.
534pub async fn log2(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
535 let num = args.get_number()?;
536 let result = inner_log2(num)?;
537
538 Ok(args.make_user_val_from_f64(result))
539}
540
541/// Compute the base 2 logarithm of the number.
542///
543/// ```no_run
544/// exampleSketch = startSketchOn("XZ")
545/// |> startProfileAt([0, 0], %)
546/// |> line(end = [log2(100), 0])
547/// |> line(end = [5, 8])
548/// |> line(end = [-10, 0])
549/// |> close()
550///
551/// example = extrude(exampleSketch, length = 5)
552/// ```
553#[stdlib {
554 name = "log2",
555 tags = ["math"],
556}]
557fn inner_log2(num: f64) -> Result<f64, KclError> {
558 Ok(num.log2())
559}
560
561/// Compute the base 10 logarithm of the number.
562pub async fn log10(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
563 let num = args.get_number()?;
564 let result = inner_log10(num)?;
565
566 Ok(args.make_user_val_from_f64(result))
567}
568
569/// Compute the base 10 logarithm of the number.
570///
571/// ```no_run
572/// exampleSketch = startSketchOn("XZ")
573/// |> startProfileAt([0, 0], %)
574/// |> line(end = [log10(100), 0])
575/// |> line(end = [5, 8])
576/// |> line(end = [-10, 0])
577/// |> close()
578///
579/// example = extrude(exampleSketch, length = 5)
580/// ```
581#[stdlib {
582 name = "log10",
583 tags = ["math"],
584}]
585fn inner_log10(num: f64) -> Result<f64, KclError> {
586 Ok(num.log10())
587}
588
589/// Compute the natural logarithm of the number.
590pub async fn ln(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
591 let num = args.get_number()?;
592 let result = inner_ln(num)?;
593
594 Ok(args.make_user_val_from_f64(result))
595}
596
597/// Compute the natural logarithm of the number.
598///
599/// ```no_run
600/// exampleSketch = startSketchOn("XZ")
601/// |> startProfileAt([0, 0], %)
602/// |> line(end = [ln(100), 15])
603/// |> line(end = [5, -6])
604/// |> line(end = [-10, -10])
605/// |> close()
606///
607/// example = extrude(exampleSketch, length = 5)
608/// ```
609#[stdlib {
610 name = "ln",
611 tags = ["math"],
612}]
613fn inner_ln(num: f64) -> Result<f64, KclError> {
614 Ok(num.ln())
615}
616
617/// Return the value of Euler’s number `e`.
618pub async fn e(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
619 let result = inner_e()?;
620
621 Ok(args.make_user_val_from_f64(result))
622}
623
624/// Return the value of Euler’s number `e`.
625///
626/// **DEPRECATED** use the constant E
627///
628/// ```no_run
629/// exampleSketch = startSketchOn("XZ")
630/// |> startProfileAt([0, 0], %)
631/// |> angledLine({
632/// angle = 30,
633/// length = 2 * e() ^ 2,
634/// }, %)
635/// |> yLine(endAbsolute = 0)
636/// |> close()
637///
638/// example = extrude(exampleSketch, length = 10)
639/// ```
640#[stdlib {
641 name = "e",
642 tags = ["math"],
643 deprecated = true,
644}]
645fn inner_e() -> Result<f64, KclError> {
646 Ok(std::f64::consts::E)
647}
648
649/// Return the value of `tau`. The full circle constant (τ). Equal to 2π.
650pub async fn tau(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
651 let result = inner_tau()?;
652
653 Ok(args.make_user_val_from_f64(result))
654}
655
656/// Return the value of `tau`. The full circle constant (τ). Equal to 2π.
657///
658/// **DEPRECATED** use the constant TAU
659///
660/// ```no_run
661/// exampleSketch = startSketchOn("XZ")
662/// |> startProfileAt([0, 0], %)
663/// |> angledLine({
664/// angle = 50,
665/// length = 10 * tau(),
666/// }, %)
667/// |> yLine(endAbsolute = 0)
668/// |> close()
669///
670/// example = extrude(exampleSketch, length = 5)
671/// ```
672#[stdlib {
673 name = "tau",
674 tags = ["math"],
675 deprecated = true,
676}]
677fn inner_tau() -> Result<f64, KclError> {
678 Ok(std::f64::consts::TAU)
679}
680
681/// Converts a number from degrees to radians.
682pub async fn to_radians(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
683 let num = args.get_number()?;
684 let result = inner_to_radians(num)?;
685
686 Ok(args.make_user_val_from_f64(result))
687}
688
689/// Converts a number from degrees to radians.
690///
691/// ```no_run
692/// exampleSketch = startSketchOn("XZ")
693/// |> startProfileAt([0, 0], %)
694/// |> angledLine({
695/// angle = 50,
696/// length = 70 * cos(toRadians(45)),
697/// }, %)
698/// |> yLine(endAbsolute = 0)
699/// |> close()
700///
701/// example = extrude(exampleSketch, length = 5)
702/// ```
703#[stdlib {
704 name = "toRadians",
705 tags = ["math"],
706}]
707fn inner_to_radians(num: f64) -> Result<f64, KclError> {
708 Ok(num.to_radians())
709}
710
711/// Converts a number from radians to degrees.
712pub async fn to_degrees(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
713 let num = args.get_number()?;
714 let result = inner_to_degrees(num)?;
715
716 Ok(args.make_user_val_from_f64(result))
717}
718
719/// Converts a number from radians to degrees.
720///
721/// ```no_run
722/// exampleSketch = startSketchOn("XZ")
723/// |> startProfileAt([0, 0], %)
724/// |> angledLine({
725/// angle = 50,
726/// length = 70 * cos(toDegrees(pi()/4)),
727/// }, %)
728/// |> yLine(endAbsolute = 0)
729/// |> close()
730///
731/// example = extrude(exampleSketch, length = 5)
732/// ```
733#[stdlib {
734 name = "toDegrees",
735 tags = ["math"],
736}]
737fn inner_to_degrees(num: f64) -> Result<f64, KclError> {
738 Ok(num.to_degrees())
739}
740
741#[cfg(test)]
742mod tests {
743 use pretty_assertions::assert_eq;
744
745 use super::*;
746
747 #[test]
748 fn test_inner_max() {
749 let nums = vec![4.0, 5.0, 6.0];
750 let result = inner_max(nums);
751 assert_eq!(result, 6.0);
752 }
753
754 #[test]
755 fn test_inner_max_with_neg() {
756 let nums = vec![4.0, -5.0];
757 let result = inner_max(nums);
758 assert_eq!(result, 4.0);
759 }
760
761 #[test]
762 fn test_inner_min() {
763 let nums = vec![4.0, 5.0, 6.0];
764 let result = inner_min(nums);
765 assert_eq!(result, 4.0);
766 }
767
768 #[test]
769 fn test_inner_min_with_neg() {
770 let nums = vec![4.0, -5.0];
771 let result = inner_min(nums);
772 assert_eq!(result, -5.0);
773 }
774}