ceil(), round(), floor() fonksiyonlarının yürütme hızı - sayfa 6

 
Nikolai Semko :

Bunun hakkında zaten burada yazdım.

TAMAM. Anladığım kadarıyla bu terminal çerçevesinde ve belirtilen doğruluk dahilinde yazıyorsunuz, kodu başka bir cihaz veya platformda taşımak ve çalıştırmakla ilgilenmiyorsunuz.

Samimi olarak.

PS İyi bir programcı, donanımın ve programın değişebileceğini ve gelecekte hatalardan kaçınmak gerektiğini anlamalıdır. sizinki gibi bir problem cümlesi ile, o zaman yanılmaz kabul edeceğiniz bir fonksiyonda, gelecekte bir hata bulmanız sizin için kolay olmayabilir.
 
Andrey Kisselyov :
TAMAM. Anladığım kadarıyla bu terminal çerçevesinde ve belirtilen doğruluk dahilinde yazıyorsunuz, kodu başka bir cihaz veya platformda taşımak ve çalıştırmakla ilgilenmiyorsunuz.

Samimi olarak.

Aynen öyle. MQL5'ten bahsediyoruz (belki MQL4 de - kontrol etmedi). Ayrıca, sınıflar veya algoritmalar içindeki kod, MQL içinde mükemmel bir şekilde aktarılacaktır. Ama C++'da da çalışacak. Örneklerim var zaten.

 
Andrey Kisselyov :

PS İyi bir programcı, donanımın ve programın değişebileceğini ve gelecekte hatalardan kaçınmak gerektiğini anlamalıdır. sizinki gibi bir problem cümlesi ile, o zaman yanılmaz kabul edeceğiniz bir fonksiyonda, gelecekte bir hata bulmanız sizin için kolay olmayabilir.
Bu durumda, bahsettiğiniz değişiklikleri hayal etmek bile imkansız. (int)(x+0.5) hesaplamasının matematiği ile ne değişebilir? Kesirli kısmı atmayı bırakacak mı yoksa ne?
 
Nikolai Semko :
Bu durumda, bahsettiğiniz değişiklikleri hayal etmek bile imkansız. (int)(x+0.5) hesaplamasının matematiği ile ne değişebilir? Kesirli kısmı atmayı bırakacak mı yoksa ne?

Örneğin, yeni bir veri türü tanıtılacak...

 
STARIJ :

Örneğin, yeni bir veri türü tanıtılacak...

))) Evet, ancak eski veri türü iptal edilirse kod çalışmayı durduracaktır ....
 
bu karışıklıktan bahsediyorum
y=( int )(x+ 0.9999999999999997 );

örnek olarak alalım:
makinenin bitliğini değiştirseniz bile 64 bite geçtiniz ve makinenin doğruluğu artırılsa bile formülünüz çalışmayı durduracaktır çünkü makinenin doğruluğu hatanızda belirlediğinizden çok daha fazla olacaktır.

Samimi olarak.

PS Formülünüzün belirli sayıda sayı üzerinde başarısız olacağı başka seçenekler de olabilir. Başka bir makineye geçiş veya derleyicide size haber verilmeyen değişiklikler veya bir sayının makinedeki gösterimi değiştiğinde veya derleme yaparken sayının kesirli kısmının azalması nedeniyle sürekli bir hata alıyor. terminalin yeni sürümleri ... ama neyin değişebileceğini asla bilemezsiniz, bence pek iyi değil. bir EĞER yapın veya hatayı tekrar tekrar yazarak daha sonra ne olacağını tahmin edin ...

Bence düşünülecek bir şey var.

 
Andrey Kisselyov :

...

PS double tanımı gereği bir tam sayı olamaz, makinenin belleğindeki sayının gösterimi değişmeyecektir.

Muhtemelen double formatının tamsayı veri türleri için geçerli olmadığı ve bir tamsayı değeri olan bir sayıyı double type değişkeninde saklayamayacağınız gerçeğinden bahsediyorsunuzdur? Double olan tamsayı.

 

Bilgisayarlarda uygulanan yuvarlamanın toplamdan sonraki en basit kesimlerden nasıl farklı olduğuna dair basit bir açıklama buldum. On dört yıl önce, http://delphimaster.net/view/14-10885/all :

Tolik ( 2003-08-13 11:04 ) [11]

Bu yuvarlama muhasebede kabul edilir. Buna göre vergi dairesi de bu yuvarlamayı uyguluyor, yani her şey en azından kağıt üzerinde yakınsamalı :))



DiamondShark ( 2003-08-13 11:20 ) [12]

Oh-ho-ho... Bir kez daha.
Sayıların dağılımının tek tip rastgeleye yakın olduğunu varsayalım. Ardından, "aritmetik" yuvarlama ile şunları elde ederiz:

Rakam Doğruluğu
0 0
on bir
2-2
3-3
4-4
5+5
6+4
7+3
8+2
9+1

Görülmesi kolay olduğu gibi, daha sonra toplanması gereken çok sayıda sayı varsa (belge pozisyonları, hesap bakiyesi vb. için toplam), o zaman "aritmetik" yuvarlama ile, beklenti ile ilgili sistematik bir hata olacaktır. biriktirmek
0,5*10^n*0,1*N
nerede:
n -- yuvarlamanın gerçekleştirildiği basamağın ondalık ağırlığı (iki basamağa kadar n=-2, tam sayılara kadar n=0 vb.)
0.1 -- her basamağın olasılığı
N -- dizideki toplam sayıların sayısı

Hata olasılıklarını eşitlemek için, sadece telafi edilmemiş (yukarıdaki tabloya bakınız) hata +5'i telafi etmek gerekir. Bunu yapmak için, önceki rakamın paritesine bağlı olarak, yapay olarak iki eşit olası +5 -5'e bölünür.

Bu arada, FPU durum word'ünde yuvarlama modunu (aritmetik/hesaplama) kontrol eden bir bayrak var.


Teklifi sonlandır

Bir diğeri, http://delphimaster.net/view/15-1340952214/all : "sıradan bir kullanıcıya (yönetici / muhasebeci) 12.5 ve 13.5'in neden farklı sonuçlar verdiğini açıklayamayacağınız için."


Kullanıcıya yuvarlama işlevlerinin "hızlandırılmış" versiyonlarını vermek, onu eklerken artan bir hata verdikleri konusunda güçlü bir şekilde uyarmak zorunda kalacaktır. Bu hatayı çok farklı durumlarda dikkatli bir şekilde değerlendirmemiz gerekecek. Bu tehlikelidir, hataların birikmesiyle doludur. Sadece yuvarlama ile işlemci yükünün oranının o kadar önemli olduğu ortaya çıktı ki, bu durumda biriken hataları unutabileceğiniz bir örnek bulmakta zorlanıyorum.

Округление чисел. Неужели ТАК правильно???
  • delphimaster.net
3-10545           Kati                  2003-08-12 10:13  2003.09.04   обновление SQL запроса 14-10898          kalishenko            2003-08-14 20:09  2003.09.04   Win2000 Server и доступ в Интернет 1-10692           lww                   2003-08-20 10:30  2003.09.04   Как написать dll для 1С? 1-10813           koks                  2003-08-20...
 

Andrey Kisselyov :
я говорю про вот это безобразие

y=( int )(x+ 0.9999999999999997 );

Pekala, beyler mükemmel öğrenciler, ikna oldum. Tavan fonksiyonunu sizin için değiştiriyorum:

y= ceil (x);  ->  y=(x-( int )x> 0 )?( int )x+ 1 :( int )x;
или через дефайн:
#define _ceil(x) (x-( int )x> 0 )?( int )x+ 1 :( int )x

bu değişken, değişkenden %25-50 daha yavaştır: y=( int )(x+ 0.99999999999999997 ); Ancak diğer yandan, mümkün olduğu kadar doğrudur, negatif sayılar için aynı şekilde çalışır ve aynı zamanda ceil(x) işlevinden yaklaşık 3 kat daha hızlıdır.

Ama ben, sıradan biri ve bir C öğrencisi olarak, dokuzlu seçeneği kullanacağım, çünkü Tüm argümanlarınızın sıkıcı olduğunu düşünüyorum ve benim için, montajcıda uzun süredir programlama yapan ve bu nedenle derlemeden sonra koda ne olduğunu hayal eden bir kişi için, onlarsız yapabileceğiniz kontrolleri koymak aşırıya kaçmaktır.

 

Pozitif ve negatif sayılar için varyant:

 #define _ceil(x) (x-( int )x> 0 )?( int )x+ 1 :( int )x
#define _round(x) (x> 0 )?( int )(x+ 0.5 ):( int )(x- 0.5 )
#define _floor(x) (x> 0 )?( int )x:(( int )x-x> 0 )?( int )x- 1 :( int )x
Bu, 3-4 kat hız artışı sağlayan ceil(), round(), floor() işlevlerinin tam teşekküllü bir ikamesi için zaten bir uygulama gibi görünüyor.
Neden: