Írj be egy vagy több kifejezést (pl. sin(x)/x, 2x^2 - 3, (cos(t), sin(3t)), r = 1 + cos(θ), x^2 + y^2 = 4) - a szerver PHP-ben, egy SAJÁT, kézzel írt kifejezés-parserrel (tokenizálás → szintaxisfa → biztonságos, fehérlistás kiértékelés) értelmezi és mintavételezi a görbéket. Nincs eval(): a bemenet SOSEM válik futtatott kódká.
// Elsőbbség: az unáris mínusz a hatvány FÖLÖTT él, a kitevő jobbra köt
// unary := ('-'|'+') unary | power
// power := postfix ('^' unary)? // -2^2 = -4, 2^3^2 = 512
// Implicit szorzás (2x, 3sin(x), (x+1)(x-1)) a '*'-gal azonos szinten:
if ($this->startsPrimary($this->current())) {
$node = Node::binary('*', $node, $this->parsePower(), true);
}
// Fehérlistás dispatch - SOSEM dinamikus "$name(...)" hívás vagy eval()
return match ($name) {
'sin' => sin($x),
'gamma' => SpecialFunctions::gamma($x),
'log' => count($a) === 1 ? log10($x) : self::logBase($a[0], $a[1]),
// ...
};
// Szakadás-keresés: ha két szomszédos minta közt nagy az ugrás, felezzük
for ($k = 0; $k < 44; $k++) {
$mid = ($xl + $xr) / 2;
$ym = $f($mid);
if (abs($ym - $yl) >= abs($yr - $ym)) { $xr = $mid; $yr = $ym; } else { $xl = $mid; $yl = $ym; }
}
// az ugrás nem csökkent: pólus vagy ugrás, a két ág NEM kapcsolódikImplicit szorzás
2x, 3sin(x), (x+1)(x-1), 2piHatvány (jobbra köt)
x^2, x**2, x², 2^3^2 = 512, -x^2 = -(x²)Abszolútérték, faktoriális
|x - 1|, 5!, x!Gyök, Unicode
√(x+1), π, ×, ·, −, ≤, ≥, ≠Feltétel, darabonként
if(x<0, -x, x^2), piecewise(x<-1, -1, x<1, x, 1)Összehasonlítás, logika
0 < x < 5, x>0 and x<3, not x==2Tartomány-megszorítás
x^2 {x > 0}, sin(x) {0 <= x <= 3}Paraméteres görbe
(cos(t), sin(3t))Polár görbe
r = 1 + cos(θ)Implicit görbe
x^2 + y^2 = 4Összeg, szorzat
sum(k, 1, 20, sin(k*x)/k)Paraméterek (csúszka)
a*sin(b*x + c)Magyar és angol nevek
tg, ctg, arctg, sh, ch, lg, ln, log(2, 8)A legegyszerűbb, de veszélyes megoldás az eval() lenne: ez a beírt szöveget közvetlenül PHP-kódként futtatná le, ami tetszőleges kód végrehajtását tenné lehetővé a szerveren - ez az oldal ezért soha nem használ eval()-t.
A biztonságos megoldás egy saját kifejezés-parser: a szöveget tokenekre bontja (számok, operátorok, függvénynevek, zárójelek, Unicode jelek), majd szintaxisfát épít belőle, amely a precedenciát (a -x^2 jelentése -(x²), a 2^3^2 jobbról köt), az implicit szorzást (2x, 3sin(x)) és az abszolútérték-jelet is helyesen kezeli. A fenti matematikai előnézet pontosan ezt a szerver által épített fát rajzolja ki.
A kiértékelés a fát bejárva csak egy szigorúan fehérlistás függvénykészletet enged meg - egy ismeretlen név azonnal hibát dob (és megmondja, hol, sőt azt is, mire gondolhattál). Minden numerikus bemenet szorított: legfeljebb 8 kifejezés, 200 karakter egyenként, korlátos mintaszám, rácsméret és időkeret.
A szakadásokat a szerver felismeri: ahol a függvény nincs értelmezve, a vonal megszakad; az aszimptotánál (1/x, tan x) és az ugrásnál (floor) az intervallum-felezés kideríti, hogy a két mintapont közt valódi szakadás van-e, és ha igen, nem köti össze őket. A sin(x)/x a 0-ban a kétoldali határértékből pótolódik. A gyököket bisection-nel, az implicit görbéket marching squares-sel, az integrált Gauss-Legendre kvadratúrával számolja.
Ez az oldal Google Analytics-et használ a látogatottság méréséhez. Ehhez a hozzájárulásod szükséges - részletek az adatvédelmi tájékoztatóban. Adatvédelmi tájékoztató