@@ -3789,6 +3789,99 @@ class AlgebraicNumber_base(sage.structure.element.FieldElement):
3789
3789
sage: AA(sqrt(65537)) # needs sage.symbolic
3790
3790
256.0019531175495?
3791
3791
"""
3792
+ def ceil (self ):
3793
+ """
3794
+ Return the ceiling of self, the smallest integer >= self.
3795
+
3796
+ This method first check if the number is algebraically an integer.
3797
+ If not, it checks if the number is real. If it is real (and not
3798
+ an integer), it uses numerical interval methods to find the ceiling.
3799
+ If the number is complex with a non-zero imaginary part, it raises
3800
+ a TypeError, as ceiling is typically not defined for such numbers.
3801
+
3802
+ EXAMPLES::
3803
+
3804
+ sage: QQbar(37/10).ceil()
3805
+ 4
3806
+ sage: QQbar(-37/10).ceil()
3807
+ -3
3808
+ sage: QQbar(4).ceil()
3809
+ 4
3810
+ sage: QQbar(0).ceil()
3811
+ 0
3812
+ sage: ceil(QQbar(sqrt(8)) - 2*QQbar(sqrt(2))) # Test case from #39345
3813
+ 0
3814
+ sage: QQbar(sqrt(2)).ceil()
3815
+ 2
3816
+ sage: QQbar(-sqrt(2)).ceil()
3817
+ -1
3818
+ sage: AA(sqrt(2)).ceil() # Works for AA too
3819
+ 2
3820
+
3821
+ sage: ceil(QQbar(3/2 + 10^(-100)*I)) # Testing complex near real
3822
+ Traceback (most recent call last):
3823
+ ...
3824
+ TypeError: ceil() not defined for complex numbers with non-zero imaginary part
3825
+ """
3826
+ if self .is_integer ():
3827
+ return ZZ (self )
3828
+
3829
+ imag_part = self .imag ()
3830
+ if not imag_part .is_zero ():
3831
+ raise TypeError ("ceil() not defined for complex numbers with non-zero imaginary part" )
3832
+
3833
+ # If the number is real and confirmed not an integer, use the interval refinement method.
3834
+ # We need to ensure we operate on an AlgebraicReal instance to call _floor_ceil.
3835
+ # AA._floor_ceil is defined in the AlgebraicReal subclass.
3836
+ real_self = AA (self )
3837
+ return real_self ._floor_ceil (lambda x : x .ceil ())
3838
+
3839
+ def floor (self ):
3840
+ """
3841
+ Return the floor of self, the largest integer <= self.
3842
+
3843
+ This method first checks if the number is algebraically an integer.
3844
+ If not, it checks if the number is real. If it is real (and not
3845
+ an integer), it uses numerical interval methods to find the floor.
3846
+ If the number is complex with a non-zero imaginary part, it raises
3847
+ a TypeError, as floor is typically not defined for such numbers.
3848
+
3849
+ EXAMPLES::
3850
+
3851
+ sage: QQbar(37/10).floor()
3852
+ 3
3853
+ sage: QQbar(-37/10).floor()
3854
+ -4
3855
+ sage: QQbar(4).floor()
3856
+ 4
3857
+ sage: QQbar(0).floor()
3858
+ 0
3859
+ sage: floor(QQbar(sqrt(8)) - 2*QQbar(sqrt(2))) # Test case from #39345
3860
+ 0
3861
+ sage: QQbar(sqrt(2)).floor()
3862
+ 1
3863
+ sage: QQbar(-sqrt(2)).floor()
3864
+ -2
3865
+ sage: AA(sqrt(2)).floor() # Works for AA too
3866
+ 1
3867
+
3868
+ sage: floor(QQbar(3/2 + 10^(-100)*I)) # Testing complex near real
3869
+ Traceback (most recent call last):
3870
+ ...
3871
+ TypeError: floor() not defined for complex numbers with non-zero imaginary part
3872
+ """
3873
+ # Check for exact integer FIRST.
3874
+ if self .is_integer ():
3875
+ return ZZ (self )
3876
+
3877
+ # Check if the number is real.
3878
+ imag_part = self .imag ()
3879
+ if not imag_part .is_zero ():
3880
+ raise TypeError ("floor() not defined for complex numbers with non-zero imaginary part" )
3881
+
3882
+ # If it's real and confirmed not an integer, use the interval refinement method.
3883
+ real_self = AA (self )
3884
+ return real_self ._floor_ceil (lambda x : x .floor ())
3792
3885
3793
3886
def __init__ (self , parent , x ):
3794
3887
r"""
0 commit comments