我编写了这个C代码,用二分法比较两个函数的根。我的第一个函数(g(x))正确执行,但第二个函数(h(x))在屏幕上输出“#1QO”。我在代码中找不到我做错了什么。
你可以解释一下吗? 任何形式的帮助将受到高度赞赏。谢谢!#include <stdio.h>
#include <math.h>
typedef double (*DFD) (double);
double g (double x)
{
double y;
y = pow (x,3) - pow (x,2)-1;
return y;
}
double h (double x)
{
double k;
k = 1.0 + (1.0/x) + (1.0 /pow (x,2));
return k;
}
double bisection (DFD f, double x0, double x1,double tol)
{
int i;
double middle;
for (i=1;i<=50;) {
middle = (x0+x1)/2.0;
if (fabs (middle - x0) <tol) return middle;
if (f(middle)* f(x0) <0.0) x1 = middle;
else x0 = middle;
}
}
int main () {
double root_gx, root_hx = 0.0;
root_gx = bisection (g,0,2,0.0005);
printf ("Root found using g(x) = %.3lf\n",root_gx);
root_hx = bisection (h,1,2,0.0005);
printf ("Root found using h(x) = %.3lf\n",root_hx);
printf ("Difference between the two roots = %.3lf\n", (fabs (root_gx- root_hx)));
return 0;
}
编辑:在二等分中初始化i = 1并将bisection (h,0,2,0.0005)
更改为bisection (h,1,2,0.0005)
并且它可以正常工作谢谢大家!
答案 0 :(得分:4)
未初始化的值导致未定义的行为。设置为某个值。
// int i;
int i = 0;
...
for (;i<=50;) {
i
永远不会增加
50
是任意的。
建议每次迭代使用double
的二进制精度为bisection()
半。
for (i=0; i <= DBL_MANT_DIG; i++) {
...
}
return middle;
还建议更改算法以允许更改|差异| 0.0的公差为0.0。
// if (fabs (middle - x0) <tol) return middle;
if (fabs (middle - x0) <= tol) return middle;
答案 1 :(得分:1)
public class GamePanel extends SurfaceView implements SurfaceHolder.Callback {
private static ImageView imgView;
public static final int WIDTH = 856;
public static final int HEIGHT = 480;
public static final int MOVESPEED = -5;
private long smokeStartTime;
private long missileStartTime;
private MainThread thread;
private Background bg;
private Player player;
private ArrayList<Smokepuff> smoke;
private ArrayList<Missile> missiles;
private ArrayList<TopBorder> topborder;
private ArrayList<BotBorder> botborder;
private Random rand = new Random();
private int maxBorderHeight;
private int minBorderHeight;
private boolean topDown = true;
private boolean botDown = true;
private boolean newGameCreated;
private Animation animation = new Animation();
MediaPlayer mSound;
MediaPlayer mySound;
public static SharedPreferences prefs;
private String saveScore = "highScore";
//increase to slow down difficulty progression, decrease to speed up difficulty progression
private int progressDenom = 20;
private Explosion explosion;
private long startReset;
private boolean reset;
private boolean dissapear;
private boolean started;
public static Context mContext;
ImageButton imgButton;
public GamePanel(Context context) {
super(context);
this.mContext = context;
//add the callback to the surfaceholder to intercept events
getHolder().addCallback(this);
//make gamePanel focusable so it can handle events
setFocusable(true);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
int counter = 0;
while (retry && counter < 1000) {
counter++;
try {
thread.setRunning(false);
thread.join();
retry = false;
thread = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
bg = new Background(BitmapFactory.decodeResource(getResources(), R.drawable.grassbg1));
player = new Player(BitmapFactory.decodeResource(getResources(), R.drawable.helicopter), 65, 25, 3);
smoke = new ArrayList<Smokepuff>();
missiles = new ArrayList<Missile>();
topborder = new ArrayList<TopBorder>();
botborder = new ArrayList<BotBorder>();
smokeStartTime = System.nanoTime();
missileStartTime = System.nanoTime();
thread = new MainThread(getHolder(), this);
//we can safely start the game loop
thread.setRunning(true);
thread.start();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (!player.getPlaying() && newGameCreated && reset) {
player.setPlaying(true);
player.setUp(true);
}
if (player.getPlaying()) {
if (!started) started = true;
reset = false;
player.setUp(true);
}
mSound = MediaPlayer.create(mContext, R.raw.helicoptor);
mSound.start();
if (!player.getPlaying() && newGameCreated && reset) {
mSound.stop();
}
return true;
}
if (event.getAction() == MotionEvent.ACTION_UP) {
player.setUp(false);
return true;
}
return super.onTouchEvent(event);
}
public void update()
{
if (player.getPlaying()) {
if (botborder.isEmpty()) {
player.setPlaying(false);
return;
}
if (topborder.isEmpty()) {
player.setPlaying(false);
return;
}
bg.update();
player.update();
//calculate the threshold of height the border can have based on the score
//max and min border heart are updated, and the border switched direction when either max or
//min is met
maxBorderHeight = 30 + player.getScore() / progressDenom;
//cap max border height so that borders can only take up a total of 1/2 the screen
if (maxBorderHeight > HEIGHT / 4) maxBorderHeight = HEIGHT / 4;
minBorderHeight = 5 + player.getScore() / progressDenom;
//check bottom border collision
for (int i = 0; i < botborder.size(); i++) {
if (collision(botborder.get(i), player))
player.setPlaying(false);
}
//check top border collision
for (int i = 0; i < topborder.size(); i++) {
if (collision(topborder.get(i), player))
player.setPlaying(false);
}
//update top border
this.updateTopBorder();
//udpate bottom border
this.updateBottomBorder();
//add missiles on timer
long missileElapsed = (System.nanoTime() - missileStartTime) / 1000000;
if (missileElapsed > (2000 - player.getScore() / 4)) {
//first missile always goes down the middle
if (missiles.size() == 0) {
missiles.add(new Missile(BitmapFactory.decodeResource(getResources(), R.drawable.
missile), WIDTH + 10, HEIGHT / 2, 45, 15, player.getScore(), 13));
} else {
missiles.add(new Missile(BitmapFactory.decodeResource(getResources(), R.drawable.missile),
WIDTH + 10, (int) (rand.nextDouble() * (HEIGHT - (maxBorderHeight * 2)) + maxBorderHeight), 45, 15, player.getScore(), 13));
}
//reset timer
missileStartTime = System.nanoTime();
}
//loop through every missile and check collision and remove
for (int i = 0; i < missiles.size(); i++) {
//update missile
missiles.get(i).update();
if (collision(missiles.get(i), player)) {
missiles.remove(i);
player.setPlaying(false);
mSound = MediaPlayer.create(mContext, R.raw.exploding);
mSound.start();
if (!player.getPlaying() && newGameCreated && reset) {
mSound.stop();
}
break;
}
//remove missile if it is way off the screen
if (missiles.get(i).getX() < -100) {
missiles.remove(i);
break;
}
}
//add smoke puffs on timer
long elapsed = (System.nanoTime() - smokeStartTime) / 1000000;
if (elapsed > 120) {
smoke.add(new Smokepuff(player.getX(), player.getY() + 10));
smokeStartTime = System.nanoTime();
}
for (int i = 0; i < smoke.size(); i++) {
smoke.get(i).update();
if (smoke.get(i).getX() < -10) {
smoke.remove(i);
}
}
} else {
player.resetDY();
if (!reset) {
newGameCreated = false;
startReset = System.nanoTime();
reset = true;
dissapear = true;
explosion = new Explosion(BitmapFactory.decodeResource(getResources(), R.drawable.explosion), player.getX(),
player.getY() - 30, 100, 100, 25);
}
explosion.update();
long resetElapsed = (System.nanoTime() - startReset) / 1000000;
if (resetElapsed > 2500 && !newGameCreated) {
newGame();
}
}
}
public boolean collision(GameObject a, GameObject b) {
if (Rect.intersects(a.getRectangle(), b.getRectangle())) {
mSound = MediaPlayer.create(mContext, R.raw.exploding);
mSound.start();
if (!player.getPlaying() && newGameCreated && reset) {
mSound.stop();
}
return true;
}
return false;
}
@SuppressLint("MissingSuperCall")
@Override
public void draw(Canvas canvas) {
final float scaleFactorX = getWidth() / (WIDTH * 1.f);
final float scaleFactorY = getHeight() / (HEIGHT * 1.f);
if (canvas != null) {
final int savedState = canvas.save();
canvas.scale(scaleFactorX, scaleFactorY);
bg.draw(canvas);
if (!dissapear) {
player.draw(canvas);
}
//draw smokepuffs
for (Smokepuff sp : smoke) {
sp.draw(canvas);
}
//draw missiles
for (Missile m : missiles) {
m.draw(canvas);
}
//draw topborder
for (TopBorder tb : topborder) {
tb.draw(canvas);
}
//draw botborder
for (BotBorder bb : botborder) {
bb.draw(canvas);
}
//draw explosion
if (started) {
explosion.draw(canvas);
}
drawText(canvas);
canvas.restoreToCount(savedState);
}
}
public void updateTopBorder() {
//every 50 points, insert randomly placed top blocks that break the pattern
if (player.getScore() % 50 == 0) {
topborder.add(new TopBorder(BitmapFactory.decodeResource(getResources(), R.drawable.brick
), topborder.get(topborder.size() - 1).getX() + 20, 0, (int) ((rand.nextDouble() * (maxBorderHeight
)) + 1)));
}
for (int i = 0; i < topborder.size(); i++) {
topborder.get(i).update();
if (topborder.get(i).getX() < -20) {
topborder.remove(i);
//remove element of arraylist, replace it by adding a new one
//calculate topdown which determines the direction the border is moving (up or down)
if (topborder.get(topborder.size() - 1).getHeight() >= maxBorderHeight) {
topDown = false;
}
if (topborder.get(topborder.size() - 1).getHeight() <= minBorderHeight) {
topDown = true;
}
//new border added will have larger height
if (topDown) {
topborder.add(new TopBorder(BitmapFactory.decodeResource(getResources(),
R.drawable.brick), topborder.get(topborder.size() - 1).getX() + 20,
0, topborder.get(topborder.size() - 1).getHeight() + 1));
}
//new border added wil have smaller height
else {
topborder.add(new TopBorder(BitmapFactory.decodeResource(getResources(),
R.drawable.brick), topborder.get(topborder.size() - 1).getX() + 20,
0, topborder.get(topborder.size() - 1).getHeight() - 1));
}
}
}
}
public void updateBottomBorder() {
//every 40 points, insert randomly placed bottom blocks that break pattern
if (player.getScore() % 40 == 0) {
botborder.add(new BotBorder(BitmapFactory.decodeResource(getResources(), R.drawable.brick),
botborder.get(botborder.size() - 1).getX() + 20, (int) ((rand.nextDouble()
* maxBorderHeight) + (HEIGHT - maxBorderHeight))));
}
//update bottom border
for (int i = 0; i < botborder.size(); i++) {
botborder.get(i).update();
//if border is moving off screen, remove it and add a corresponding new one
if (botborder.get(i).getX() < -20) {
botborder.remove(i);
//determine if border will be moving up or down
if (botborder.get(botborder.size() - 1).getY() <= HEIGHT - maxBorderHeight) {
botDown = true;
}
if (botborder.get(botborder.size() - 1).getY() >= HEIGHT - minBorderHeight) {
botDown = false;
}
if (botDown) {
botborder.add(new BotBorder(BitmapFactory.decodeResource(getResources(), R.drawable.brick
), botborder.get(botborder.size() - 1).getX() + 20, botborder.get(botborder.size() - 1
).getY() + 1));
} else {
botborder.add(new BotBorder(BitmapFactory.decodeResource(getResources(), R.drawable.brick
), botborder.get(botborder.size() - 1).getX() + 20, botborder.get(botborder.size() - 1
).getY() - 1));
}
}
}
}
public void newGame() {
dissapear = false;
botborder.clear();
topborder.clear();
missiles.clear();
smoke.clear();
minBorderHeight = 5;
maxBorderHeight = 30;
player.resetDY();
player.resetScore();
player.setY(HEIGHT / 2);
//create initial borders
//initial top border
for (int i = 0; i * 20 < WIDTH + 40; i++) {
//first top border create
if (i == 0) {
topborder.add(new TopBorder(BitmapFactory.decodeResource(getResources(), R.drawable.brick
), i * 20, 0, 10));
} else {
topborder.add(new TopBorder(BitmapFactory.decodeResource(getResources(), R.drawable.brick
), i * 20, 0, topborder.get(i - 1).getHeight() + 1));
}
}
//initial bottom border
for (int i = 0; i * 20 < WIDTH + 40; i++) {
//first border ever created
if (i == 0) {
botborder.add(new BotBorder(BitmapFactory.decodeResource(getResources(), R.drawable.brick)
, i * 20, HEIGHT - minBorderHeight));
}
//adding borders until the initial screen is filed
else {
botborder.add(new BotBorder(BitmapFactory.decodeResource(getResources(), R.drawable.brick),
i * 20, botborder.get(i - 1).getY() - 1));
}
}
newGameCreated = true;
}
public void drawText(Canvas canvas) {
SharedPreferences prefs = mContext.getSharedPreferences("PrefsKeys", Context.MODE_PRIVATE);
int oldScore = prefs.getInt("highScore", 0);
int newScore = Player.getScore() * 3;
//update score only if new score is higher
if (newScore > oldScore) {
SharedPreferences.Editor editor = prefs.edit();
editor.putInt("highScore", newScore);
editor.commit();
}
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(30);
paint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
canvas.drawText("DISTANCE: " + newScore, 10, HEIGHT - 10, paint);
canvas.drawText("HighScore: " + oldScore, WIDTH - 215, HEIGHT - 10, paint);
if (!player.getPlaying() && newGameCreated && reset) {
Paint paint1 = new Paint();
paint1.setTextSize(40);
paint1.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
canvas.drawText("PRESS TO START", WIDTH / 2 - 50, HEIGHT / 2, paint1);
paint1.setTextSize(20);
canvas.drawText("PRESS AND HOLD TO GO UP", WIDTH / 2 - 50, HEIGHT / 2 + 20, paint1);
canvas.drawText("RELEASE TO GO DOWN", WIDTH / 2 - 50, HEIGHT / 2 + 40, paint1);
}
}
}
public class settingsMenu extends Activity implements View.OnClickListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
FrameLayout game = new FrameLayout(this);
GamePanel gameView = new GamePanel (this);
ImageButton myButton = new ImageButton(this);
myButton.setId(1);
myButton.setImageResource(R.drawable.settings);
RelativeLayout b1 = new RelativeLayout(this);
RelativeLayout.LayoutParams buttonParams =
new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
b1.addView(myButton, buttonParams);
game.addView(gameView);
game.addView(b1);
setContentView(game);
myButton.setOnClickListener(this);
}
public void onClick(View v) {
Intent intent = new Intent(this, GamePanel.class);
startActivity(intent);
}
}
如果double h (double x)
{
double k;
k = 1.0 + (1.0/x) + (1.0 /pow (x,2));
return k;
}
,将除以0。如果您拨打x==0.0
,并拨打bisection (h,0,2,0.0005);
,则会执行此操作,在这种情况下为f(x0)
。
如果在函数中除以输入参数,则应始终检查输入参数的实际值是否不等于h(0.0);
:
0.0