Passer de h=(b-a) /n à n= ? dans un programme
Bonjour,
Je subdivise [a, b] avec le pas h=(b-a)/n . avec n un entier et a, b et h des réels
Supposons connaitre h par exemple 0.01. comment implémenter le n dans un programme c
Je subdivise [a, b] avec le pas h=(b-a)/n . avec n un entier et a, b et h des réels
Supposons connaitre h par exemple 0.01. comment implémenter le n dans un programme c
n = (int) ((b-a) / h) ;
ou
n = (int) ((b-a) / h)+1 ;
car on a le problème maths si h=(b-a)/n, on ne peut pas dire que n=(b-a)/h.
Lorsque notre cher Nico, le professeur, intervient dans une question d'analyse, c'est une véritable joie pour les lecteurs..
Réponses
-
Je ferais ceil((b-a) / h) (avec b > a) en sachant que le dernier intervalle peut avoir une taille différente de hIl ne faut pas respirer la compote, ça fait tousser.
J'affirme péremptoirement que toute affirmation péremptoire est fausse -
Si comme tu le dis $n$ est un int et que $a$, $b$ et $h$ sont des float alors je ferais juste n=(b-a)/h; car en c le cast se fera automatiquement.affiche 559.
#include <stdio.h> int main(void) { int n ; float h, a, b ; a = 3.3; b = 8.9 ; h = 0.01 ; n = (b-a) / h; printf("%d\n", n) ; }
-
dp j'ai vu d'autres qui mettent
n = (b-a) / h +1
Lorsque notre cher Nico, le professeur, intervient dans une question d'analyse, c'est une véritable joie pour les lecteurs.. -
Tout dépend de la précision que tu veux. Tu peux remarquer que dans mon code, le résultat n'est pas juste : 559 au lieu de 560. Par contre, l'inverse est aussi vrai : dans certains cas tu te retrouveras avec le bon résultat et donc avec le risque d'avoir n+1.Au pire tu peux gérer les différents cas en jouant avec fmod(v,1) pour vérifier la partie décimale de ton float et adapter selon celle-ci. Un peu comme cela :
int cast(float a, float b, float h) { float tmp = (b-a)/h ; return fmod(tmp,1) < 0.5 ? (int)tmp : (int)tmp+1 ; }
-
Soit la solution de Mediat-supreme, soit, pour les allergiques à la fonction ceil :
n = (b-a)/h if n*h <(b-a) { n++ }
Tu me dis, j'oublie. Tu m'enseignes, je me souviens. Tu m'impliques, j'apprends. Benjamin Franklin
L'hypocrisie est pire qu'une vérité qui fait mal. Franck Ntasamara. -
Utiliser ceil est selon moi une erreur. Si le résultat est par exemple 55.4, tu te retrouveras avec 56 et pas 55. De même avec floor qui renverra 55 pour 55.6 au lieu de 56.
-
Voici un comparatif#include <stdio.h>
int main(void) {
int n ;
int N ;
float h, a, b, h1, h2 ;
a = 3.3;
b = 8.9 ;
h = 0.01 ;
n = (b-a) / h ;
N = ((b-a) / h)+1;
h1= (b-a) / n;
h2= (b-a) / N;
printf("%d\n" "%d\n" "%lf\n" "%lf\n" , n, N , h1, h2 ) ;Les résultats559
560
0.010018
0.010000
Lorsque notre cher Nico, le professeur, intervient dans une question d'analyse, c'est une véritable joie pour les lecteurs.. -
Utilise la fonction cast que je t'ai écrite plus haut et tu auras le bon résultat à chaque fois, ramené à l'entier le plus proche. (ps. attention, j'ai édité pour enlever le = qui était en trop).
-
Je viens de voir ce postLorsque notre cher Nico, le professeur, intervient dans une question d'analyse, c'est une véritable joie pour les lecteurs..
-
Je ne comprends pas un truc selon que je déclare n un entier ou un float
#include <stdio.h>int main(void) {int n ;float a, b, h, N ;a = 3.3;b = 8.9 ;h = 0.01 ;n = (b-a) / h ;N = (b-a) / h ;printf("%d\n" "%lf\n" , n, N ) ;}
J 'ai les résultats559559.999939Qu'est-ce qui est précis ?dp un truc peux-tu m'expliquer le rôle de int avant main et le rôle de void après mainint main(void) {Lorsque notre cher Nico, le professeur, intervient dans une question d'analyse, c'est une véritable joie pour les lecteurs.. -
En informatique il y a toujours des erreurs de précision sur les réels. C'est la raison pour laquelle tu n'obtiens pas 560.0 mais 559.999939. La conversion automatique en int est en réalité une troncature et donc récupère simplement la partie entière de ton réel : 559.En C main doit toujours renvoyer un entier : 0 si aucune erreur ne s'est produite, un entier définit s’il y a eu une erreur d'où int main(). Usuellement si une erreur se produit et qu'on n'a pas déjà défini de code on utilise 1 ou -1. int main(void) pour indiquer que main ne prend par d'argument, mais tu peux utiliser int main() si tu veux, cela revient au même.
-
Au vu du besoin initial, on avait a, b et h fixés. Et on cherchait n pour que a+n*h atteigne ou dépasse b.
Le but n'était pas de recalculer h après coup.
C'était écrit :Je subdivise [a, b] avec le pas h=(b-a)/n . avec n un entier et a, b et h des réelsIci, tu recalcules h, et tu fais tes tests en prenant un cas assez particulier : la division de b-a par h tombe juste (à part les problèmes de précision).
Supposons connaitre h par exemple 0.01. comment implémenter le n dans un programme c
À partir des données a=1, b=2 et h= 0.3, tu veux obtenir quelle valeur pour n ? 3 ou 4.Tu me dis, j'oublie. Tu m'enseignes, je me souviens. Tu m'impliques, j'apprends. Benjamin Franklin
L'hypocrisie est pire qu'une vérité qui fait mal. Franck Ntasamara. -
Quand même lourran, on choisit n qui rend fidèlement le h de la formule h=(b-a)/n. d'où la légitimité des tests.
Lorsque notre cher Nico, le professeur, intervient dans une question d'analyse, c'est une véritable joie pour les lecteurs.. -
Dans ce cas ma fonction cast est ce qu'il te faut car tu obtiendras à chaque fois l'entier le plus proche par distance.
-
dp pour toi c'est facile , j'essaie de voir le comment pour utiliser cette fonctionLorsque notre cher Nico, le professeur, intervient dans une question d'analyse, c'est une véritable joie pour les lecteurs..
-
Bah juste en faisant
n = cast(a,b,h);
Et si jamais tu cherches fmod, il faut inclure math.h#include <math.h>
-
On a aussi la formule round(x)=floor(x+1/2)
-
dp a dit :Utiliser ceil est selon moi une erreur. Si le résultat est par exemple 55.4, tu te retrouveras avec 56 et pas 55.
pour découper [0; 1.03] en intervalles de taille 0.1, c'est clairement impossible, on peut choisir :- Ajuster la taille des subdivisions
- Accepter de ne pas aller au bout
- Accepter de dépasser
- Aller au bout, mais la dernière subdivision est plus petite que les autres
Le +1 systématique est toujours fautif
Il ne faut pas respirer la compote, ça fait tousser.
J'affirme péremptoirement que toute affirmation péremptoire est fausse -
Certes. Toutefois je me place toujours dans le cas où @gebrane enseigne tout ceci à ses étudiants et je cherche à lui donner le code le plus simple et facile à comprendre (encore que, à trop me creuser la tête pour trouver un truc "facile" je me suis éloigné de cette voie tandis que @Boécien a fait plus simple), et surtout, dont le comportement se rapproche finalement le plus possible de ce que ces derniers peuvent attendre.
-
tu etais plus rapide#include <stdio.h>int main(void){int n ;float a, b, h, N ;a = 3.3;b = 8.9 ;h = 0.01 ;int cast(float a, float b, float h) {float tmp = (b-a)/h ;return fmod(tmp,1) < 0.5 ? (int)tmp : (int)tmp+1 ;}printf("%d\n", cast(a,b,h)) ;}Lorsque notre cher Nico, le professeur, intervient dans une question d'analyse, c'est une véritable joie pour les lecteurs..
-
@gebrane Écris comme tu l'as fait cast est locale à main et ne pourra être utilisée que dans cette dernière (et après avoir été défini). Considère donc plutôt de le faire comme ceci :
#include <stdio.h> #include <math.h> int cast(float a, float b, float h) { float tmp = (b-a)/h ; return fmod(tmp,1) < 0.5 ? (int)tmp : (int)tmp+1 ; // ou comme @"Boécien" l'a écrit // return floor(tmp+1/2) ; } int main(void) { int n ; float h, a, b ; a = 3.3; b = 8.9 ; h = 0.01 ; n = cast(a,b,h); printf("%d\n", n) ; return 0; }
-
dans ce exemple ca rend 232 pourquoi? car on est dans la 231,5#include <stdio.h>int main(void){int n ;float a, b, h, N ;a = 1;b = 3.315 ;h = 0.01 ;int cast(float a, float b, float h) {float tmp = (b-a)/h ;return fmod(tmp,1) < 0.5 ? (int)tmp : (int)tmp+1 ;}printf("%d\n", cast(a,b,h)) ;}Je dois comprendre ce genre de questions pour ne pas me faire ridiculiséLorsque notre cher Nico, le professeur, intervient dans une question d'analyse, c'est une véritable joie pour les lecteurs..
-
Parce que j'ai choisi avec fmod(tmp,1) < 0.5 de considérer que tous les nombres de [x.50, x+1[ donneraient x+1.
-
Je repose ma question, restée sans réponse :
si a=1 et b=2 et h=0.3, on veut obtenir quelle valeur pour n par cet 'outil' .
J'insiste parce que cette question me paraît essentielle. D'ailleurs, Mediat-Supreme a résolu le truc, en disant : si on veut tel résultat, voici la recette, et si on veut tel autre résultat, voici l'autre recette.
Un problème bien posé est un problème à moitié résolu.Tu me dis, j'oublie. Tu m'enseignes, je me souviens. Tu m'impliques, j'apprends. Benjamin Franklin
L'hypocrisie est pire qu'une vérité qui fait mal. Franck Ntasamara. -
lourrain tu as donné un mauvais exemple car dans ton cas le (b-a)/h est d 'office un entier, l entier 3Lorsque notre cher Nico, le professeur, intervient dans une question d'analyse, c'est une véritable joie pour les lecteurs..
-
Donc la fonction ceil() n'est pas adaptée. Tu veux un arrondi-inférieur, ou peut-être un arrondi à l'entier le plus proche. Tu ne veux pas un arrondi supérieur.
Tu me dis, j'oublie. Tu m'enseignes, je me souviens. Tu m'impliques, j'apprends. Benjamin Franklin
L'hypocrisie est pire qu'une vérité qui fait mal. Franck Ntasamara. -
Surtout je ne veux pas sortir de l'intervalle d'étude [0,T], je crois que l'approche de dp est le mieuxLorsque notre cher Nico, le professeur, intervient dans une question d'analyse, c'est une véritable joie pour les lecteurs..
-
C'est surtout qu'il s'agit de la manière la plus "naturelle" lorsqu'on veut approcher un réel par un entier : prendre l'entier le plus "proche", justement.
-
J'ai implémenté ce cast dans mon programme. Cependant, j'ai une question : comment faire un graphique sous C ? J'ai cherché sur le net et j'ai trouvé gnuplot. Est-ce une façon débile de représenter un ensemble de mesures ?
Ci-dessous, vous trouverez un programme qui modélise la cinétique d'une réaction d'ordre 2. La concentration obéit à l'équation différentielle $C'(t)=-kC(t)^2$ avec une condition initiale $C(0)$. j'ai programmé le problème $y'(t)=-y²(t),\quad y(0)=1$ sur [0,T] avec h=0.03mn(1.8s) et T =20mn
#include <stdio.h>#include <math.h>double f(double x, double y){return -y * y +x ; // j'ai ajouté un x pour rendre difficile la recherche d'une solution analytique}int cast(double T, double h) {double tmp = T/h ;return fmod(tmp,1) < 0.5 ? (int)tmp : (int)tmp+1 ;}int main() {double h = 0.03;double T=20;int n ;n=cast(T,h);double k1,k2,k3,k4, x[n+1], y[n+1];x[0] = 0, y[0] = 1;for (int i = 0; i <= n - 1; i++) {x[i] = i* h;k1 = f(x[i], y[i]);k2 = f(x[i] + 0.5*h, y[i] + 0.5*h*k1);k3 = f(x[i] + 0.5*h, y[i] + 0.5*h*k2);k4 = f(x[i]+h, y[i]+h);y[i + 1] = y[i] + h*(k1 + 2*k2 + 2*k3 + k4)/6;}FILE *fp;fp = fopen("data1.dat", "w");for (int i = 0; i < n; i++) {fprintf(fp, "%lf %lf %lf\n", x[i], y[i]);}fclose(fp);FILE *gnuplotPipe = popen("\"C:\\Program Files\\gnuplot\\bin\\gnuplot\" -persistent", "w");fprintf(gnuplotPipe, "set xlabel 'x'\n");fprintf(gnuplotPipe, "set ylabel 'y(x)'\n");fprintf(gnuplotPipe, "plot 'data1.dat' using 1:2 with lines title 'Runge Kutta4\n");fflush(gnuplotPipe);return 0;}Lorsque notre cher Nico, le professeur, intervient dans une question d'analyse, c'est une véritable joie pour les lecteurs.. -
-
ce n'est pas de refus ce programme en rust ou ada ou Xcas ou JavaLorsque notre cher Nico, le professeur, intervient dans une question d'analyse, c'est une véritable joie pour les lecteurs..
-
Bah aidé de tout ce que j'ai déjà écrit en rust ici tu peux essayer de le faire toi-même. Tu peux aussi m'envoyer des messages privés pour me demander de l'aide si jamais tu coinces.
-
Je collectionne les programmes. je ne vais pas étudier rust pour le moment sinon je vais me perdre entre C et rust
Je n'oblige personne que cela soit claireLorsque notre cher Nico, le professeur, intervient dans une question d'analyse, c'est une véritable joie pour les lecteurs.. -
double f(double x, double y) { return -y * y ; }
À quoi sert le $x$ ?
-
car j 'avais en fait programmé des équations du type $y'(x)=-y^2(x)+g(x)$
je vais ajouter un x dans la fonction pour rendre la recherche d'une solution exacte impossibleLorsque notre cher Nico, le professeur, intervient dans une question d'analyse, c'est une véritable joie pour les lecteurs.. -
use gnuplot::{Figure, Caption, Color} ; fn f(_x: f64, y:f64) -> f64 { -y*y } fn main() { let (h,t): (f64,f64) = (0.03, 20.0) ; let n: usize = (t/h) as usize; let mut k: Vec<f64> = vec![0.0; 4] ; let mut x: Vec<f64> = vec![0.0; n] ; let mut y: Vec<f64> = vec![1.0; n+1] ; for i in 0..n { x[i] = h*i as f64 ; k[0] = f(x[i], y[i]); k[1] = f(x[i] + 0.5*h, y[i] + 0.5*h*k[0]); k[2] = f(x[i] + 0.5*h, y[i] + 0.5*h*k[1]); k[3] = f(x[i]+h, y[i]+h); y[i+1] = y[i] + h*(k[0]+2.0*k[1]+2.0*k[2]+k[3])/6.0 ; } let mut fig = Figure::new(); fig.axes2d().lines(&x, &y, &[Caption("Runge Kutta"), Color("blue")]) ; fig.show().expect("An error occurs when generating the plot...") ; }
-
Il est stylé rust. Beau à regarder. J'ai hâte à étudier ce langage. MerciLorsque notre cher Nico, le professeur, intervient dans une question d'analyse, c'est une véritable joie pour les lecteurs..
-
Ce n'est pas pour rien que je t'ai recommandé de l'utiliser avec tes étudiants, ou bien même go qui en réalité serait sans doute mieux pour ces derniers. Plein de soucis (ou avantages, dépend d'où tu te places) du c disparaissent avec rust. Celui-ci te permet de te concentrer sur le fait de programmer ce qu'y t’intéresse plutôt que de passer ton temps à comprendre pourquoi ça ne fonctionne pas comme tu le souhaites…Ainsi, par principe de moindre surprise par exemple, pas besoin de s'embêter avec les erreurs de précisions en rust; dans les petits cas comme celui qui nous intéresse, il le gère de manière attendue pour nous.
Connectez-vous ou Inscrivez-vous pour répondre.
Bonjour!
Catégories
- 165.1K Toutes les catégories
- 59 Collège/Lycée
- 22.1K Algèbre
- 37.5K Analyse
- 6.3K Arithmétique
- 58 Catégories et structures
- 1.1K Combinatoire et Graphes
- 13 Sciences des données
- 5.1K Concours et Examens
- 20 CultureMath
- 51 Enseignement à distance
- 2.9K Fondements et Logique
- 10.7K Géométrie
- 83 Géométrie différentielle
- 1.1K Histoire des Mathématiques
- 79 Informatique théorique
- 3.9K LaTeX
- 39K Les-mathématiques
- 3.5K Livres, articles, revues, (...)
- 2.7K Logiciels pour les mathématiques
- 24 Mathématiques et finance
- 337 Mathématiques et Physique
- 5K Mathématiques et Société
- 3.3K Pédagogie, enseignement, orientation
- 10.1K Probabilités, théorie de la mesure
- 801 Shtam
- 4.2K Statistiques
- 3.8K Topologie
- 1.4K Vie du Forum et de ses membres