# Why are the p-values for a binomial test very different from the p-values for a chi-squared test?

I am testing if a coin is fair by throwing it n-times and having n/2 + sqrt(n) heads.

However, I get very different p-values from both binomial and chi-squared tests. In particular the relative difference (chis_p - bin_p)/chis_p is close to 50% even when n grows larger and larger.

I already read the post Does a 2*2 chi-square test give the same results as a binomial test? that says that the differences may be due to the implementation. But I think 50% of the difference is far too big and so would like to know if there is something else going on.

The following is the code:

import matplotlib.pyplot as plt
from scipy.stats import binom
from scipy.stats import chi2

# Probability of heads for a fair coin

# Calculate p-value using the binomial test
# The alternative='greater' indicates we are looking at the probability of getting at least 'heads' number of heads

return p_value

# Calculate tails

# Expected frequency of heads and tails for a fair coin
expected = tosses / 2

# Calculate chi-squared statistic
chi_squared_stat = ((heads - expected)**2 / expected) + ((tails - expected)**2 / expected)

# Calculate p-value using the chi-squared test with 1 degree of freedom
p_value = chi2.sf(chi_squared_stat, 1)

return p_value

bin_p_list = []
chis_p_list = []
diff_list = []
relative_diff_list = []
step = 100
for tosses in range(step, step*1000, step):
diff_p = chis_p - bin_p
relative_diff = 100*diff_p/chis_p
bin_p_list.append(bin_p)
chis_p_list.append(chis_p)
diff_list.append(diff_p)
relative_diff_list.append(relative_diff)

plt.plot(bin_p_list, label='Binomial p-value')
plt.plot(chis_p_list, label='Chi-squared p-value')
plt.title('P-values for binomial and chi-squared tests for n/2 + sqrt(n) heads on n coin throws')
plt.xlabel('Number of coin throws')
plt.ylabel('p-value')
plt.legend()
plt.show()

plt.plot(relative_diff_list)
plt.title('Relative difference (chis_p - bin_p)/chis_p in p-values')
plt.xlabel('Number of coin throws')
plt.ylabel('Relative difference [%]')
plt.show()


I also include the plots that you can produce with the code.