@@ -579,7 +579,223 @@ static ecma_completion_value_t
579
579
ecma_builtin_number_prototype_object_to_precision (ecma_value_t this_arg, /* *< this argument */
580
580
ecma_value_t arg) /* *< routine's argument */
581
581
{
582
- ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, arg);
582
+ ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
583
+
584
+ /* 1. */
585
+ ECMA_OP_TO_NUMBER_TRY_CATCH (this_num, this_arg, ret_value);
586
+
587
+ /* 2. */
588
+ if (ecma_is_value_undefined (arg))
589
+ {
590
+ ret_value = ecma_builtin_number_prototype_object_to_string (this_arg, NULL , 0 );
591
+ }
592
+ else
593
+ {
594
+ /* 3. */
595
+ ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
596
+
597
+ /* 4. */
598
+ if (ecma_number_is_nan (this_num))
599
+ {
600
+ ecma_string_t *nan_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_NAN);
601
+ ret_value = ecma_make_normal_completion_value (ecma_make_string_value (nan_str_p));
602
+ }
603
+ else
604
+ {
605
+ bool is_negative = false ;
606
+
607
+ /* 6. */
608
+ if (ecma_number_is_negative (this_num) && !ecma_number_is_zero (this_num))
609
+ {
610
+ is_negative = true ;
611
+ this_num *= -1 ;
612
+ }
613
+
614
+ /* 7. */
615
+ if (ecma_number_is_infinity (this_num))
616
+ {
617
+ ecma_string_t *infinity_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_INFINITY_UL);
618
+
619
+ if (is_negative)
620
+ {
621
+ ecma_string_t *neg_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_MINUS_CHAR);
622
+ ecma_string_t *neg_inf_str_p = ecma_concat_ecma_strings (neg_str_p, infinity_str_p);
623
+ ecma_deref_ecma_string (infinity_str_p);
624
+ ecma_deref_ecma_string (neg_str_p);
625
+ ret_value = ecma_make_normal_completion_value (ecma_make_string_value (neg_inf_str_p));
626
+ }
627
+ else
628
+ {
629
+ ret_value = ecma_make_normal_completion_value (ecma_make_string_value (infinity_str_p));
630
+ }
631
+ }
632
+ /* 8. */
633
+ else if (arg_num < 1.0 || arg_num >= 22.0 )
634
+ {
635
+ ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_RANGE));
636
+ }
637
+ else
638
+ {
639
+ uint64_t digits = 0 ;
640
+ int32_t num_digits = 0 ;
641
+ int32_t exponent = 1 ;
642
+
643
+ int32_t precision = ecma_number_to_int32 (arg_num);
644
+
645
+ /* Get the parameters of the number if non-zero. */
646
+ if (!ecma_number_is_zero (this_num))
647
+ {
648
+ ecma_number_to_decimal (this_num, &digits, &num_digits, &exponent);
649
+ }
650
+
651
+ digits = ecma_builtin_number_prototype_helper_round (digits, num_digits - precision);
652
+
653
+ int buffer_size;
654
+ if (exponent < -5 || exponent > precision)
655
+ {
656
+ /* Exponential notation, precision + 1 digits for number, 5 for exponent, 1 for \0 */
657
+ buffer_size = precision + 1 + 5 + 1 ;
658
+ }
659
+ else if (exponent <= 0 )
660
+ {
661
+ /* Fixed notation, -exponent + 2 digits for leading zeros, precision digits, 1 for \0 */
662
+ buffer_size = -exponent + 2 + precision + 1 ;
663
+ }
664
+ else
665
+ {
666
+ /* Fixed notation, precision + 1 digits for number, 1 for \0 */
667
+ buffer_size = precision + 1 + 1 ;
668
+ }
669
+
670
+ if (is_negative)
671
+ {
672
+ buffer_size++;
673
+ }
674
+
675
+ MEM_DEFINE_LOCAL_ARRAY (buff, buffer_size, lit_utf8_byte_t );
676
+ lit_utf8_byte_t *actual_char_p = buff;
677
+
678
+ uint64_t scale = 1 ;
679
+
680
+ /* Calculate the magnitude of the number. This is used to get the digits from left to right. */
681
+ while (scale <= digits)
682
+ {
683
+ scale *= 10 ;
684
+ }
685
+
686
+ if (is_negative)
687
+ {
688
+ *actual_char_p++ = ' -' ;
689
+ }
690
+
691
+ int digit = 0 ;
692
+
693
+ /* 10.c, Exponential notation.*/
694
+ if (exponent < -5 || exponent > precision)
695
+ {
696
+ /* Add significant digits. */
697
+ for (int i = 1 ; i <= precision; i++)
698
+ {
699
+ digit = 0 ;
700
+ scale /= 10 ;
701
+ while (digits >= scale && scale > 0 )
702
+ {
703
+ digits -= scale;
704
+ digit++;
705
+ }
706
+
707
+ *actual_char_p++ = (lit_utf8_byte_t ) (digit + ' 0' );
708
+
709
+ if (i == 1 && i != precision)
710
+ {
711
+ *actual_char_p++ = ' .' ;
712
+ }
713
+ }
714
+
715
+ *actual_char_p++ = ' e' ;
716
+
717
+ exponent--;
718
+ if (exponent < 0 )
719
+ {
720
+ exponent *= -1 ;
721
+ *actual_char_p++ = ' -' ;
722
+ }
723
+ else
724
+ {
725
+ *actual_char_p++ = ' +' ;
726
+ }
727
+
728
+ /* Get magnitude of exponent. */
729
+ int32_t scale_expt = 1 ;
730
+ while (scale_expt <= exponent)
731
+ {
732
+ scale_expt *= 10 ;
733
+ }
734
+ scale_expt /= 10 ;
735
+
736
+ /* Add exponent digits. */
737
+ if (exponent == 0 )
738
+ {
739
+ *actual_char_p++ = ' 0' ;
740
+ }
741
+ else
742
+ {
743
+ while (scale_expt > 0 )
744
+ {
745
+ digit = exponent / scale_expt;
746
+ exponent %= scale_expt;
747
+ *actual_char_p++ = (lit_utf8_byte_t ) (digit + ' 0' );
748
+ scale_expt /= 10 ;
749
+ }
750
+ }
751
+ }
752
+ /* Fixed notation. */
753
+ else
754
+ {
755
+ /* Add leading zeros if neccessary. */
756
+ if (exponent <= 0 )
757
+ {
758
+ *actual_char_p++ = ' 0' ;
759
+ *actual_char_p++ = ' .' ;
760
+ for (int i = exponent; i < 0 ; i++)
761
+ {
762
+ *actual_char_p++ = ' 0' ;
763
+ }
764
+ }
765
+
766
+ /* Add significant digits. */
767
+ for (int i = 1 ; i <= precision; i++)
768
+ {
769
+ digit = 0 ;
770
+ scale /= 10 ;
771
+ while (digits >= scale && scale > 0 )
772
+ {
773
+ digits -= scale;
774
+ digit++;
775
+ }
776
+
777
+ *actual_char_p++ = (lit_utf8_byte_t ) (digit + ' 0' );
778
+
779
+ if (i == exponent && i != precision)
780
+ {
781
+ *actual_char_p++ = ' .' ;
782
+ }
783
+ }
784
+ }
785
+
786
+ JERRY_ASSERT (actual_char_p - buff < buffer_size);
787
+ *actual_char_p = ' \0 ' ;
788
+ ecma_string_t *str_p = ecma_new_ecma_string_from_utf8 (buff, (lit_utf8_size_t ) (actual_char_p - buff));
789
+
790
+ ret_value = ecma_make_normal_completion_value (ecma_make_string_value (str_p));
791
+ MEM_FINALIZE_LOCAL_ARRAY (buff);
792
+ }
793
+ }
794
+ ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
795
+ }
796
+ ECMA_OP_TO_NUMBER_FINALIZE (this_num);
797
+
798
+ return ret_value;
583
799
} /* ecma_builtin_number_prototype_object_to_precision */
584
800
585
801
/* *
0 commit comments