src/HOL/Library/Float.thy
changeset 63248 414e3550e9c0
parent 63040 eb4ddd18d635
child 63356 77332fed33c3
equal deleted inserted replaced
63247:c7c76fa73a56 63248:414e3550e9c0
   855 qualified lemma compute_float_up[code]: "float_up p x = - float_down p (-x)"
   855 qualified lemma compute_float_up[code]: "float_up p x = - float_down p (-x)"
   856   by transfer (simp add: round_down_uminus_eq)
   856   by transfer (simp add: round_down_uminus_eq)
   857 
   857 
   858 end
   858 end
   859 
   859 
   860 
   860 definition floorlog :: "nat \<Rightarrow> nat \<Rightarrow> nat"
   861 subsection \<open>Compute bitlen of integers\<close>
   861   where "floorlog b a = (if a > 0 \<and> b > 1 then nat \<lfloor>log b a\<rfloor> + 1 else 0)"
   862 
   862 
   863 definition bitlen :: "int \<Rightarrow> int"
   863 lemma floorlog_nonneg: "0 \<le> floorlog b x"
   864   where "bitlen a = (if a > 0 then \<lfloor>log 2 a\<rfloor> + 1 else 0)"
   864 proof -
   865 
   865   have "-1 < log b (-x)" if "0 > x" "b > 1"
   866 lemma bitlen_nonneg: "0 \<le> bitlen x"
       
   867 proof -
       
   868   have "-1 < log 2 (-x)" if "0 > x"
       
   869   proof -
   866   proof -
   870     have "-1 = log 2 (inverse 2)"
   867     have "-1 = log b (inverse b)" using that
   871       by (subst log_inverse) simp_all
   868       by (subst log_inverse) simp_all
   872     also have "\<dots> < log 2 (-x)"
   869     also have "\<dots> < log b (-x)"
   873       using \<open>0 > x\<close> by auto
   870       using \<open>0 > x\<close> by auto
   874     finally show ?thesis .
   871     finally show ?thesis .
   875   qed
   872   qed
   876   then show ?thesis
   873   then show ?thesis
   877     unfolding bitlen_def by (auto intro!: add_nonneg_nonneg)
   874     unfolding floorlog_def by (auto intro!: add_nonneg_nonneg)
   878 qed
   875 qed
       
   876 
       
   877 lemma floorlog_bounds:
       
   878   assumes "x > 0" "b > 1"
       
   879   shows "b ^ (floorlog b x - 1) \<le> x \<and> x < b ^ (floorlog b x)"
       
   880 proof
       
   881   show "b ^ (floorlog b x - 1) \<le> x"
       
   882   proof -
       
   883     have "(b::real) ^ nat \<lfloor>log b (real_of_int x)\<rfloor> = b powr real_of_int \<lfloor>log b (real_of_int x)\<rfloor>"
       
   884       using powr_realpow[symmetric, of b "nat \<lfloor>log b (real_of_int x)\<rfloor>"] \<open>x > 0\<close> \<open>b > 1\<close>
       
   885       by simp
       
   886     also have "\<dots> \<le> b powr log b (real_of_int x)"
       
   887       using \<open>b > 1\<close>
       
   888       by simp
       
   889     also have "\<dots> = real_of_int x"
       
   890       using \<open>0 < x\<close> \<open>b > 1\<close> by simp
       
   891     finally have "b ^ nat \<lfloor>log b (real_of_int x)\<rfloor> \<le> real_of_int x"
       
   892       by simp
       
   893     then show ?thesis
       
   894       using \<open>0 < x\<close> \<open>b > 1\<close> of_nat_le_iff
       
   895       by (fastforce simp add: floorlog_def)
       
   896   qed
       
   897   show "x < b ^ (floorlog b x)"
       
   898   proof -
       
   899     have "x \<le> b powr (log b x)"
       
   900       using \<open>x > 0\<close> \<open>b > 1\<close> by simp
       
   901     also have "\<dots> < b powr (\<lfloor>log b x\<rfloor> + 1)"
       
   902       using assms
       
   903       by (intro powr_less_mono) auto
       
   904     also have "\<dots> = b ^ nat (\<lfloor>log b (real_of_int x)\<rfloor> + 1)"
       
   905       using assms
       
   906       by (simp add: powr_realpow[symmetric])
       
   907     finally
       
   908     have "x < b ^ nat (\<lfloor>log (real b) (real_of_int (int x))\<rfloor> + 1)"
       
   909       by (rule of_nat_less_imp_less)
       
   910     then show ?thesis
       
   911       using \<open>x > 0\<close> \<open>b > 1\<close>
       
   912       by (simp add: floorlog_def nat_add_distrib)
       
   913   qed
       
   914 qed
       
   915 
       
   916 lemma floorlog_power[simp]:
       
   917   assumes "a > 0" "b > 1"
       
   918   shows "floorlog b (a * b ^ c) = floorlog b a + c"
       
   919 proof -
       
   920   have "\<lfloor>log (real b) (real a) + real c\<rfloor> = \<lfloor>log (real b) (real a)\<rfloor> + c"
       
   921     by arith
       
   922   then show ?thesis using assms
       
   923     by (auto simp: floorlog_def log_mult powr_realpow[symmetric] nat_add_distrib)
       
   924 qed
       
   925 
       
   926 lemma
       
   927   floor_log_add_eqI:
       
   928   fixes a::nat and b::nat and r::real
       
   929   assumes "b > 1"
       
   930   assumes "a \<ge> 1" "0 \<le> r" "r < 1"
       
   931   shows "\<lfloor>log b (a + r)\<rfloor> = \<lfloor>log b a\<rfloor>"
       
   932 proof (rule floor_eq2)
       
   933   have "log (real b) (real a) \<le> log (real b) (real a + r)"
       
   934     using assms by force
       
   935   then show "\<lfloor>log (real b) (real a)\<rfloor> \<le> log (real b) (real a + r)"
       
   936     by arith
       
   937 next
       
   938   define l::int where "l = int b ^ (nat \<lfloor>log b a\<rfloor> + 1)"
       
   939   have l_def_real: "l = b powr (\<lfloor>log b a\<rfloor> + 1)"
       
   940     using assms by (simp add: l_def powr_add powr_real_of_int)
       
   941   have "a < l"
       
   942   proof -
       
   943     have "a = b powr (log b a)" using assms by simp
       
   944     also have "\<dots> < b powr floor ((log b a) + 1)"
       
   945       using assms(1) by auto
       
   946     also have "\<dots> = l"
       
   947       using assms
       
   948       by (simp add: l_def powr_real_of_int powr_add)
       
   949     finally show ?thesis by simp
       
   950   qed
       
   951   then have "a + r < l" using assms by simp
       
   952   then have "log b (a + r) < log b l"
       
   953     using assms by simp
       
   954   also have "\<dots> = real_of_int \<lfloor>log b a\<rfloor> + 1"
       
   955     using assms by (simp add: l_def_real)
       
   956   finally show "log b (a + r) < real_of_int \<lfloor>log b a\<rfloor> + 1" .
       
   957 qed
       
   958 
       
   959 lemma
       
   960   divide_nat_diff_div_nat_less_one:
       
   961   fixes x b::nat shows "x / b - x div b < 1"
       
   962   by (metis One_nat_def add_diff_cancel_left' divide_1 divide_self_if floor_divide_of_nat_eq
       
   963     less_eq_real_def mod_div_trivial nat.simps(3) of_nat_eq_0_iff real_of_nat_div3 real_of_nat_div_aux)
       
   964 
       
   965 context
       
   966 begin
       
   967 
       
   968 qualified lemma compute_floorlog[code]: "floorlog b x = (if x > 0 \<and> b > 1 then floorlog b (x div b) + 1 else 0)"
       
   969 proof -
       
   970   {
       
   971     assume prems: "x > 0" "b > 1" "0 < x div b"
       
   972     have "\<lfloor>log (real b) (real x)\<rfloor> = \<lfloor>log (real b) (x / b * b)\<rfloor>"
       
   973       using prems by simp
       
   974     also have "\<dots> = \<lfloor>log b (x / b) + log b b\<rfloor>"
       
   975       using prems
       
   976       by (subst log_mult) auto
       
   977     also have "\<dots> = \<lfloor>log b (x / b)\<rfloor> + 1" using prems by simp
       
   978     also have "\<lfloor>log b (x / b)\<rfloor> = \<lfloor>log b (x div b + (x / b - x div b))\<rfloor>"
       
   979       by simp
       
   980     also have "\<dots> = \<lfloor>log b (x div b)\<rfloor>"
       
   981       using prems real_of_nat_div4 divide_nat_diff_div_nat_less_one
       
   982       by (intro floor_log_add_eqI) auto
       
   983     finally have ?thesis using prems by (simp add: floorlog_def nat_add_distrib)
       
   984   } then show ?thesis
       
   985     by (auto simp: floorlog_def div_eq_0_iff intro!: floor_eq2)
       
   986 qed
       
   987 
       
   988 end
       
   989 
       
   990 definition bitlen :: "int \<Rightarrow> int" where "bitlen a = floorlog 2 (nat a)"
       
   991 
       
   992 lemma bitlen_alt_def: "bitlen a = (if a > 0 then \<lfloor>log 2 a\<rfloor> + 1 else 0)"
       
   993   by (simp add: bitlen_def floorlog_def)
       
   994 
       
   995 lemma bitlen_nonneg: "0 \<le> bitlen x"
       
   996   using floorlog_nonneg by (simp add: bitlen_def)
   879 
   997 
   880 lemma bitlen_bounds:
   998 lemma bitlen_bounds:
   881   assumes "x > 0"
   999   assumes "x > 0"
   882   shows "2 ^ nat (bitlen x - 1) \<le> x \<and> x < 2 ^ nat (bitlen x)"
  1000   shows "2 ^ nat (bitlen x - 1) \<le> x \<and> x < 2 ^ nat (bitlen x)"
   883 proof
  1001 proof -
   884   show "2 ^ nat (bitlen x - 1) \<le> x"
  1002   from assms have "bitlen x \<ge> 1" by (auto simp: bitlen_alt_def)
   885   proof -
  1003   with assms floorlog_bounds[of "nat x" 2] show ?thesis
   886     have "(2::real) ^ nat \<lfloor>log 2 (real_of_int x)\<rfloor> = 2 powr real_of_int \<lfloor>log 2 (real_of_int x)\<rfloor>"
  1004     by (auto simp add: bitlen_def le_nat_iff nat_less_iff nat_diff_distrib)
   887       using powr_realpow[symmetric, of 2 "nat \<lfloor>log 2 (real_of_int x)\<rfloor>"] \<open>x > 0\<close>
       
   888       by simp
       
   889     also have "\<dots> \<le> 2 powr log 2 (real_of_int x)"
       
   890       by simp
       
   891     also have "\<dots> = real_of_int x"
       
   892       using \<open>0 < x\<close> by simp
       
   893     finally have "2 ^ nat \<lfloor>log 2 (real_of_int x)\<rfloor> \<le> real_of_int x"
       
   894       by simp
       
   895     then show ?thesis
       
   896       using \<open>0 < x\<close> by (simp add: bitlen_def)
       
   897   qed
       
   898   show "x < 2 ^ nat (bitlen x)"
       
   899   proof -
       
   900     have "x \<le> 2 powr (log 2 x)"
       
   901       using \<open>x > 0\<close> by simp
       
   902     also have "\<dots> < 2 ^ nat (\<lfloor>log 2 (real_of_int x)\<rfloor> + 1)"
       
   903       apply (simp add: powr_realpow[symmetric])
       
   904       using \<open>x > 0\<close> apply simp
       
   905       done
       
   906     finally show ?thesis
       
   907       using \<open>x > 0\<close> by (simp add: bitlen_def ac_simps)
       
   908   qed
       
   909 qed
  1005 qed
   910 
  1006 
   911 lemma bitlen_pow2[simp]:
  1007 lemma bitlen_pow2[simp]:
   912   assumes "b > 0"
  1008   assumes "b > 0"
   913   shows "bitlen (b * 2 ^ c) = bitlen b + c"
  1009   shows "bitlen (b * 2 ^ c) = bitlen b + c"
   914 proof -
  1010   using assms
   915   from assms have "b * 2 ^ c > 0"
  1011   by (simp add: bitlen_def nat_mult_distrib nat_power_eq)
   916     by auto
       
   917   then show ?thesis
       
   918     using floor_add[of "log 2 b" c] assms 
       
   919     apply (auto simp add: log_mult log_nat_power bitlen_def)
       
   920     by (metis add.right_neutral frac_lt_1 frac_of_int of_int_of_nat_eq)
       
   921 qed
       
   922 
  1012 
   923 lemma bitlen_Float:
  1013 lemma bitlen_Float:
   924   fixes m e
  1014   fixes m e
   925   defines "f \<equiv> Float m e"
  1015   defines "f \<equiv> Float m e"
   926   shows "bitlen (\<bar>mantissa f\<bar>) + exponent f = (if m = 0 then 0 else bitlen \<bar>m\<bar> + e)"
  1016   shows "bitlen (\<bar>mantissa f\<bar>) + exponent f = (if m = 0 then 0 else bitlen \<bar>m\<bar> + e)"
   927 proof (cases "m = 0")
  1017 proof (cases "m = 0")
   928   case True
  1018   case True
   929   then show ?thesis by (simp add: f_def bitlen_def Float_def)
  1019   then show ?thesis by (simp add: f_def bitlen_alt_def Float_def)
   930 next
  1020 next
   931   case False
  1021   case False
   932   then have "f \<noteq> float_of 0"
  1022   then have "f \<noteq> float_of 0"
   933     unfolding real_of_float_eq by (simp add: f_def)
  1023     unfolding real_of_float_eq by (simp add: f_def)
   934   then have "mantissa f \<noteq> 0"
  1024   then have "mantissa f \<noteq> 0"
   941 
  1031 
   942 context
  1032 context
   943 begin
  1033 begin
   944 
  1034 
   945 qualified lemma compute_bitlen[code]: "bitlen x = (if x > 0 then bitlen (x div 2) + 1 else 0)"
  1035 qualified lemma compute_bitlen[code]: "bitlen x = (if x > 0 then bitlen (x div 2) + 1 else 0)"
   946 proof -
  1036   unfolding bitlen_def
   947   { assume "2 \<le> x"
  1037   by (subst Float.compute_floorlog) (simp add: nat_div_distrib)
   948     then have "\<lfloor>log 2 (x div 2)\<rfloor> + 1 = \<lfloor>log 2 (x - x mod 2)\<rfloor>"
       
   949       by (simp add: log_mult zmod_zdiv_equality')
       
   950     also have "\<dots> = \<lfloor>log 2 (real_of_int x)\<rfloor>"
       
   951     proof (cases "x mod 2 = 0")
       
   952       case True
       
   953       then show ?thesis by simp
       
   954     next
       
   955       case False
       
   956       define n where "n = \<lfloor>log 2 (real_of_int x)\<rfloor>"
       
   957       then have "0 \<le> n"
       
   958         using \<open>2 \<le> x\<close> by simp
       
   959       from \<open>2 \<le> x\<close> False have "x mod 2 = 1" "\<not> 2 dvd x"
       
   960         by (auto simp add: dvd_eq_mod_eq_0)
       
   961       with \<open>2 \<le> x\<close> have "x \<noteq> 2 ^ nat n"
       
   962         by (cases "nat n") auto
       
   963       moreover
       
   964       { have "real_of_int (2^nat n :: int) = 2 powr (nat n)"
       
   965           by (simp add: powr_realpow)
       
   966         also have "\<dots> \<le> 2 powr (log 2 x)"
       
   967           using \<open>2 \<le> x\<close> by (simp add: n_def del: powr_log_cancel)
       
   968         finally have "2^nat n \<le> x" using \<open>2 \<le> x\<close> by simp }
       
   969       ultimately have "2^nat n \<le> x - 1" by simp
       
   970       then have "2^nat n \<le> real_of_int (x - 1)"
       
   971         using numeral_power_le_real_of_int_cancel_iff by blast
       
   972       { have "n = \<lfloor>log 2 (2^nat n)\<rfloor>"
       
   973           using \<open>0 \<le> n\<close> by (simp add: log_nat_power)
       
   974         also have "\<dots> \<le> \<lfloor>log 2 (x - 1)\<rfloor>"
       
   975           using \<open>2^nat n \<le> real_of_int (x - 1)\<close> \<open>0 \<le> n\<close> \<open>2 \<le> x\<close> by (auto intro: floor_mono)
       
   976         finally have "n \<le> \<lfloor>log 2 (x - 1)\<rfloor>" . }
       
   977       moreover have "\<lfloor>log 2 (x - 1)\<rfloor> \<le> n"
       
   978         using \<open>2 \<le> x\<close> by (auto simp add: n_def intro!: floor_mono)
       
   979       ultimately show "\<lfloor>log 2 (x - x mod 2)\<rfloor> = \<lfloor>log 2 x\<rfloor>"
       
   980         unfolding n_def \<open>x mod 2 = 1\<close> by auto
       
   981     qed
       
   982     finally have "\<lfloor>log 2 (x div 2)\<rfloor> + 1 = \<lfloor>log 2 x\<rfloor>" . }
       
   983   moreover
       
   984   { assume "x < 2" "0 < x"
       
   985     then have "x = 1" by simp
       
   986     then have "\<lfloor>log 2 (real_of_int x)\<rfloor> = 0" by simp }
       
   987   ultimately show ?thesis
       
   988     unfolding bitlen_def
       
   989     by (auto simp: pos_imp_zdiv_pos_iff not_le)
       
   990 qed
       
   991 
  1038 
   992 end
  1039 end
   993 
  1040 
   994 lemma float_gt1_scale: assumes "1 \<le> Float m e"
  1041 lemma float_gt1_scale: assumes "1 \<le> Float m e"
   995   shows "0 \<le> e + (bitlen m - 1)"
  1042   shows "0 \<le> e + (bitlen m - 1)"
  1002   then have "m \<noteq> 0" by auto
  1049   then have "m \<noteq> 0" by auto
  1003   show ?thesis
  1050   show ?thesis
  1004   proof (cases "0 \<le> e")
  1051   proof (cases "0 \<le> e")
  1005     case True
  1052     case True
  1006     then show ?thesis
  1053     then show ?thesis
  1007       using \<open>0 < m\<close> by (simp add: bitlen_def)
  1054       using \<open>0 < m\<close> by (simp add: bitlen_alt_def)
  1008   next
  1055   next
  1009     case False
  1056     case False
  1010     have "(1::int) < 2" by simp
  1057     have "(1::int) < 2" by simp
  1011     let ?S = "2^(nat (-e))"
  1058     let ?S = "2^(nat (-e))"
  1012     have "inverse (2 ^ nat (- e)) = 2 powr e"
  1059     have "inverse (2 ^ nat (- e)) = 2 powr e"
  1046     by auto
  1093     by auto
  1047 
  1094 
  1048   have "m \<noteq> 0"
  1095   have "m \<noteq> 0"
  1049     using assms by auto
  1096     using assms by auto
  1050   have "0 \<le> bitlen m - 1"
  1097   have "0 \<le> bitlen m - 1"
  1051     using \<open>0 < m\<close> by (auto simp: bitlen_def)
  1098     using \<open>0 < m\<close> by (auto simp: bitlen_alt_def)
  1052 
  1099 
  1053   have "m < 2^nat(bitlen m)"
  1100   have "m < 2^nat(bitlen m)"
  1054     using bitlen_bounds[OF \<open>0 <m\<close>] ..
  1101     using bitlen_bounds[OF \<open>0 <m\<close>] ..
  1055   also have "\<dots> = 2^nat(bitlen m - 1 + 1)"
  1102   also have "\<dots> = 2^nat(bitlen m - 1 + 1)"
  1056     using \<open>0 < m\<close> by (auto simp: bitlen_def)
  1103     using \<open>0 < m\<close> by (auto simp: bitlen_def)
  1199   "float_round_down prec (Float m e) = (let d = bitlen \<bar>m\<bar> - int prec - 1 in
  1246   "float_round_down prec (Float m e) = (let d = bitlen \<bar>m\<bar> - int prec - 1 in
  1200     if 0 < d then Float (div_twopow m (nat d)) (e + d)
  1247     if 0 < d then Float (div_twopow m (nat d)) (e + d)
  1201              else Float m e)"
  1248              else Float m e)"
  1202   using Float.compute_float_down[of "Suc prec - bitlen \<bar>m\<bar> - e" m e, symmetric]
  1249   using Float.compute_float_down[of "Suc prec - bitlen \<bar>m\<bar> - e" m e, symmetric]
  1203   by transfer
  1250   by transfer
  1204     (simp add: field_simps abs_mult log_mult bitlen_def truncate_down_def
  1251     (simp add: field_simps abs_mult log_mult bitlen_alt_def truncate_down_def
  1205       cong del: if_weak_cong)
  1252       cong del: if_weak_cong)
  1206 
  1253 
  1207 qualified lemma compute_float_round_up[code]:
  1254 qualified lemma compute_float_round_up[code]:
  1208   "float_round_up prec x = - float_round_down prec (-x)"
  1255   "float_round_up prec x = - float_round_down prec (-x)"
  1209   by transfer (simp add: truncate_down_uminus_eq)
  1256   by transfer (simp add: truncate_down_uminus_eq)
  1247     using assms
  1294     using assms
  1248     by (linarith |
  1295     by (linarith |
  1249       auto
  1296       auto
  1250         intro!: floor_eq2
  1297         intro!: floor_eq2
  1251         intro: powr_strict powr
  1298         intro: powr_strict powr
  1252         simp: powr_divide2[symmetric] powr_add divide_simps algebra_simps bitlen_def)+
  1299         simp: powr_divide2[symmetric] powr_add divide_simps algebra_simps)+
  1253   finally
  1300   finally
  1254   show ?thesis by simp
  1301   show ?thesis by simp
  1255 qed
  1302 qed
  1256 
  1303 
  1257 lemma truncate_down_rat_precision:
  1304 lemma truncate_down_rat_precision:
  1258     "truncate_down prec (real x / real y) = round_down (rat_precision prec x y) (real x / real y)"
  1305     "truncate_down prec (real x / real y) = round_down (rat_precision prec x y) (real x / real y)"
  1259   and truncate_up_rat_precision:
  1306   and truncate_up_rat_precision:
  1260     "truncate_up prec (real x / real y) = round_up (rat_precision prec x y) (real x / real y)"
  1307     "truncate_up prec (real x / real y) = round_up (rat_precision prec x y) (real x / real y)"
  1261   unfolding truncate_down_def truncate_up_def rat_precision_def
  1308   unfolding truncate_down_def truncate_up_def rat_precision_def
  1262   by (cases x; cases y) (auto simp: floor_log_divide_eq algebra_simps bitlen_def)
  1309   by (cases x; cases y) (auto simp: floor_log_divide_eq algebra_simps bitlen_alt_def)
  1263 
  1310 
  1264 lift_definition lapprox_posrat :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> float"
  1311 lift_definition lapprox_posrat :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> float"
  1265   is "\<lambda>prec (x::nat) (y::nat). truncate_down prec (x / y)"
  1312   is "\<lambda>prec (x::nat) (y::nat). truncate_down prec (x / y)"
  1266   by simp
  1313   by simp
  1267 
  1314 
  1344 proof -
  1391 proof -
  1345   have "0 < x \<Longrightarrow> log 2 x + 1 = log 2 (2 * x)"
  1392   have "0 < x \<Longrightarrow> log 2 x + 1 = log 2 (2 * x)"
  1346     by (simp add: log_mult)
  1393     by (simp add: log_mult)
  1347   then have "bitlen (int x) < bitlen (int y)"
  1394   then have "bitlen (int x) < bitlen (int y)"
  1348     using assms
  1395     using assms
  1349     by (simp add: bitlen_def del: floor_add_one)
  1396     by (simp add: bitlen_alt_def del: floor_add_one)
  1350       (auto intro!: floor_mono simp add: floor_add_one[symmetric] simp del: floor_add floor_add_one)
  1397       (auto intro!: floor_mono simp add: floor_add_one[symmetric] simp del: floor_add floor_add_one)
  1351   then show ?thesis
  1398   then show ?thesis
  1352     using assms
  1399     using assms
  1353     by (auto intro!: pos_add_strict simp add: field_simps rat_precision_def)
  1400     by (auto intro!: pos_add_strict simp add: field_simps rat_precision_def)
  1354 qed
  1401 qed
  1575   assumes "\<lfloor>x * 2 powr (p - \<lfloor>log 2 \<bar>x\<bar>\<rfloor>)\<rfloor> = \<lfloor>y * 2 powr (p - \<lfloor>log 2 \<bar>x\<bar>\<rfloor>)\<rfloor>"
  1622   assumes "\<lfloor>x * 2 powr (p - \<lfloor>log 2 \<bar>x\<bar>\<rfloor>)\<rfloor> = \<lfloor>y * 2 powr (p - \<lfloor>log 2 \<bar>x\<bar>\<rfloor>)\<rfloor>"
  1576   shows "truncate_down p x = truncate_down p y"
  1623   shows "truncate_down p x = truncate_down p y"
  1577   using assms by (auto simp: truncate_down_def round_down_def)
  1624   using assms by (auto simp: truncate_down_def round_down_def)
  1578 
  1625 
  1579 lemma bitlen_eq_zero_iff: "bitlen x = 0 \<longleftrightarrow> x \<le> 0"
  1626 lemma bitlen_eq_zero_iff: "bitlen x = 0 \<longleftrightarrow> x \<le> 0"
  1580   by (clarsimp simp add: bitlen_def)
  1627   by (clarsimp simp add: bitlen_alt_def)
  1581     (metis Float.compute_bitlen add.commute bitlen_def bitlen_nonneg less_add_same_cancel2 not_less
  1628     (metis Float.compute_bitlen add.commute bitlen_alt_def bitlen_nonneg less_add_same_cancel2 not_less
  1582       zero_less_one)
  1629       zero_less_one)
  1583 
  1630 
  1584 lemma sum_neq_zeroI:
  1631 lemma sum_neq_zeroI:
  1585   fixes a k :: real
  1632   fixes a k :: real
  1586   shows "\<bar>a\<bar> \<ge> k \<Longrightarrow> \<bar>b\<bar> < k \<Longrightarrow> a + b \<noteq> 0"
  1633   shows "\<bar>a\<bar> \<ge> k \<Longrightarrow> \<bar>b\<bar> < k \<Longrightarrow> a + b \<noteq> 0"
  1780     using H by (intro powr_mono) auto
  1827     using H by (intro powr_mono) auto
  1781   finally have abs_m2_less_half: "\<bar>?m2\<bar> < 1 / 2"
  1828   finally have abs_m2_less_half: "\<bar>?m2\<bar> < 1 / 2"
  1782     by simp
  1829     by simp
  1783 
  1830 
  1784   then have "\<bar>real_of_int m2\<bar> < 2 powr -(?shift + 1)"
  1831   then have "\<bar>real_of_int m2\<bar> < 2 powr -(?shift + 1)"
  1785     unfolding powr_minus_divide by (auto simp: bitlen_def field_simps powr_mult_base abs_mult)
  1832     unfolding powr_minus_divide by (auto simp: bitlen_alt_def field_simps powr_mult_base abs_mult)
  1786   also have "\<dots> \<le> 2 powr real_of_int (e1 - e2 - 2)"
  1833   also have "\<dots> \<le> 2 powr real_of_int (e1 - e2 - 2)"
  1787     by simp
  1834     by simp
  1788   finally have b_less_quarter: "\<bar>?b\<bar> < 1/4 * 2 powr real_of_int e1"
  1835   finally have b_less_quarter: "\<bar>?b\<bar> < 1/4 * 2 powr real_of_int e1"
  1789     by (simp add: powr_add field_simps powr_divide2[symmetric] powr_numeral abs_mult)
  1836     by (simp add: powr_add field_simps powr_divide2[symmetric] powr_numeral abs_mult)
  1790   also have "1/4 < \<bar>real_of_int m1\<bar> / 2" using \<open>m1 \<noteq> 0\<close> by simp
  1837   also have "1/4 < \<bar>real_of_int m1\<bar> / 2" using \<open>m1 \<noteq> 0\<close> by simp
  1848         using a_half_less_sum \<open>m1 \<noteq> 0\<close> \<open>?sum \<noteq> 0\<close>
  1895         using a_half_less_sum \<open>m1 \<noteq> 0\<close> \<open>?sum \<noteq> 0\<close>
  1849         unfolding floor_diff_of_int[symmetric]
  1896         unfolding floor_diff_of_int[symmetric]
  1850         by (auto simp add: log_minus_eq_powr powr_minus_divide intro!: floor_mono)
  1897         by (auto simp add: log_minus_eq_powr powr_minus_divide intro!: floor_mono)
  1851       finally
  1898       finally
  1852       have "int p - \<lfloor>log 2 \<bar>?a + ?b\<bar>\<rfloor> \<le> p - (bitlen \<bar>m1\<bar>) - e1 + 2"
  1899       have "int p - \<lfloor>log 2 \<bar>?a + ?b\<bar>\<rfloor> \<le> p - (bitlen \<bar>m1\<bar>) - e1 + 2"
  1853         by (auto simp: algebra_simps bitlen_def \<open>m1 \<noteq> 0\<close>)
  1900         by (auto simp: algebra_simps bitlen_alt_def \<open>m1 \<noteq> 0\<close>)
  1854       also have "\<dots> \<le> - ?e"
  1901       also have "\<dots> \<le> - ?e"
  1855         using bitlen_nonneg[of "\<bar>m1\<bar>"] by (simp add: k1_def)
  1902         using bitlen_nonneg[of "\<bar>m1\<bar>"] by (simp add: k1_def)
  1856       finally show "?f \<le> - ?e" by simp
  1903       finally show "?f \<le> - ?e" by simp
  1857     qed
  1904     qed
  1858     also have "sgn ?b = sgn m2"
  1905     also have "sgn ?b = sgn m2"
  2001 
  2048 
  2002 lemma mantissa_1: "mantissa 1 = 1"
  2049 lemma mantissa_1: "mantissa 1 = 1"
  2003   using mantissa_float[of 1 0] by (simp add: one_float_def)
  2050   using mantissa_float[of 1 0] by (simp add: one_float_def)
  2004 
  2051 
  2005 lemma bitlen_1: "bitlen 1 = 1"
  2052 lemma bitlen_1: "bitlen 1 = 1"
  2006   by (simp add: bitlen_def)
  2053   by (simp add: bitlen_alt_def)
  2007 
  2054 
  2008 lemma mantissa_eq_zero_iff: "mantissa x = 0 \<longleftrightarrow> x = 0"
  2055 lemma mantissa_eq_zero_iff: "mantissa x = 0 \<longleftrightarrow> x = 0"
  2009   (is "?lhs \<longleftrightarrow> ?rhs")
  2056   (is "?lhs \<longleftrightarrow> ?rhs")
  2010 proof
  2057 proof
  2011   show ?rhs if ?lhs
  2058   show ?rhs if ?lhs